Обновление таблицы с максимальной датой другой таблицы - PullRequest
1 голос
/ 19 марта 2010

В Oracle 10g мне нужно обновить таблицу A данными из таблицы B.

Таблица A имеет РАСПОЛОЖЕНИЕ, ТРАНДАТ и СТАТУС.

Таблица B имеет LOCATION, STATUSDATE и STATUS

Мне нужно обновить столбец STATUS в таблице A с помощью столбца STATUS из таблицы B, где STATUSDATE - максимальная дата до и включая TRANDATE для этого местоположения (в основном, я получаю статус местоположения в то время конкретной транзакции).

У меня есть процедура PL / SQL, которая сделает это, но я ЗНАЮ, что должен быть способ заставить ее работать с использованием аналитики, и я слишком долго бился в голову.

Спасибо!

Ответы [ 2 ]

2 голосов
/ 19 марта 2010

это должно помочь вам начать (здесь функция MAX - это агрегатная функция, а не аналитическая функция):

UPDATE table_a
   SET status = (SELECT MAX(table_b.status) 
                        KEEP (DENSE_RANK FIRST ORDER BY table_b.statusdate DESC)
                   FROM table_b
                  WHERE table_a.location = table_b.location
                    AND table_b.statusdate <= table_a.trandate);

Это обновит все строки в table_a, даже если в table_b нет предыдущей строки, в этом случае состояние будет изменено на NULL. Если вы хотите обновить только строки в table_a, которые имеют соответствующее совпадение в table_b, вы можете добавить фильтр:

UPDATE table_a
   SET status = (SELECT MAX(table_b.status) 
                        KEEP (DENSE_RANK FIRST ORDER BY table_b.statusdate DESC)
                   FROM table_b
                  WHERE table_a.location = table_b.location
                    AND table_b.statusdate <= table_a.trandate)
 WHERE EXISTS (SELECT NULL
                 FROM table_b
                WHERE table_a.location = table_b.location
                  AND table_b.statusdate <= table_a.trandate);
0 голосов
/ 19 марта 2010

Это версия с аналитической функцией. Это обновит все строки в table_a, как показано. Чтобы обновить определенную строку, добавьте фильтр.

update table_a t1 set status = (
       select distinct
              first_value(t2.status) over (partition by t1.location, t1.trandate order by t2.statusdate desc)
       from temp_b t2 
       where t1.location = t2.location
       and t2.statusdate <= t1.trandate );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...