2015-07-09 6 views
3

Мне нужно обновить значения столбца таблицы из значения MAX другого столбца таблицы.Oracle UPDATE с INNER JOIN

Этот question - это именно то место, где у меня есть таблица, в которой мне нужно получить значение MAX, а затем обновить столбец datetime таблицы newTable с значением MAX datetime этой таблицы для всех соответствующих исходных значений в newTable.

Основываясь на данных из связанного потока, я пришел со следующим утверждением обновления

UPDATE newTable s 
SET s.datetime = (
    SELECT tt.timedate 
    FROM topten tt 
    INNER JOIN 
     (SELECT home, MAX(datetime) AS MaxDateTime 
     FROM topten 
     GROUP BY home) groupedtt 
    ON tt.home = groupedtt.home 
    AND tt.datetime = groupedtt.MaxDateTime WHERE s.home = tt.home); 

Проблема в том, что я получаю следующее сообщение об ошибке

SQL Error: ORA-01427: single-row subquery returns more than one row 

Я должен также укажите, что topten.home не является уникальным, а newTable.home.

я могу избавиться от ошибки, добавив RowNum оператор вроде так:

UPDATE newTable s 
SET s.datetime = (
    SELECT tt.timedate 
    FROM topten tt 
    INNER JOIN 
     (SELECT home, MAX(datetime) AS MaxDateTime 
     FROM topten 
     GROUP BY home) groupedtt 
    ON tt.home = groupedtt.home 
    AND tt.datetime = groupedtt.MaxDateTime WHERE s.home = tt.home AND rownum <= 1); 

или установки подзапроса для MAX

UPDATE newTable s 
SET s.datetime = (
    SELECT MAX(tt.timedate) 
    FROM topten tt 
    INNER JOIN 
     (SELECT home, MAX(datetime) AS MaxDateTime 
     FROM topten 
     GROUP BY home) groupedtt 
    ON tt.home = groupedtt.home 
    AND tt.datetime = groupedtt.MaxDateTime WHERE s.home = tt.home); 

однако я не совсем понимаю, почему это необходимо так как в заявлении MAX в исходном подзапросе должно быть указано, что есть только 1 запись на дом, и я не знаю, какое влияние эти изменения в точности (хотя первоначальные тесты предполагают, что они работают)

Я чем-то усложняю?

+0

Ни один из запросов не должен запускаться. У всех в конце есть отсутствующая закрывающая скобка. Действительно ли это запросы, которые вы используете? – sstan

+0

Это была ошибка с моей стороны при копировании. Он исправлен. Да, это те запросы, которые я запускаю, за исключением того, что данные были изменены, например, для целей. – ByteFlinger

ответ

3

Почему бы не просто ...

UPDATE newTable s 
SET s.datetime = (
    SELECT COALESCE(MAX(tt.timedate), <put your default date here>) 
    FROM topten tt 
    WHERE s.home = tt.home) 

Если взять ваше первоначальное заявление, и я удалить внутреннее соединение, например:

UPDATE newTable s 
SET s.datetime = (
    SELECT tt.timedate 
    FROM topten tt 
    WHERE s.home = tt.home); 

... вы увидите этот подзапрос может возвращать несколько строк для того же значения home. Итак, предположим, что приведенное выше возвращает 5 строк за home значение, а затем вы добавляете свое внутреннее соединение с запросом MAX и GROUP BY, который возвращает одну строку за home, он все равно вернет в общей сложности 5 x 1 строк. Магически не уменьшит количество строк до 1.

+0

Спасибо. Я не работал с SQL через некоторое время, и я ожидал, что я просто усложнил ситуацию. Похоже, ваш запрос намного более изящный, чтобы решить проблему. Что, если я хочу установить значение по умолчанию в случае, если newTable имеет некоторую домашнюю запись, не найденную в topten? – ByteFlinger

+0

Я отредактировал свой ответ, чтобы включить функцию COALESCE, чтобы вы могли указать значение по умолчанию. – sstan

+0

Большое спасибо – ByteFlinger