Обновление таблицы с использованием подзапроса (Oracle) - PullRequest
0 голосов
/ 21 октября 2019

Моя таблица имеет следующую структуру:

    HID            TIME_FROM         LAG_TIME_FROM          TIME_UNTIL
-------------------------------------------------------------------------
AAAAA12334566   06.07.19 04:04:51   13.07.19 04:05:17   13.07.19 04:05:17
AAAAA12334566   13.07.19 04:05:17   14.07.19 04:05:30   14.07.19 04:05:30
AAAAA12334566   14.07.19 04:05:30   23.07.19 22:00:00   23.07.19 22:00:00
AAAAA12334566   23.07.19 22:00:00   23.07.19 22:00:00   25.07.19 04:05:06
AAAAA12334566   23.07.19 22:00:00   25.07.19 04:05:06   22.07.19 22:00:00
AAAAA12334566   25.07.19 04:05:06   25.07.19 04:05:06   01.01.99 00:00:00
AAAAA12334566   25.07.19 04:05:06   01.01.99 00:00:00   24.07.19 04:05:06
BBBBBB12334566  29.06.18 14:59:20   01.02.19 14:25:00   01.02.19 14:25:00
BBBBBB12334566  01.02.19 14:25:00   07.03.19 04:07:48   07.03.19 04:07:48
BBBBBB12334566  07.03.19 04:07:48   05.07.19 04:04:47   09.07.19 04:04:52
BBBBBB12334566  05.07.19 04:04:47   06.07.19 04:04:51   09.07.19 04:04:52
BBBBBB12334566  06.07.19 04:04:51   08.07.19 13:00:45   09.07.19 04:04:52
BBBBBB12334566  08.07.19 13:00:45   08.07.19 13:18:19   12.07.19 04:04:44

Столбец HID, TIME_FROM и TIME_UNTIL существуют в моей таблице. Столбец LAG_TIME_FROM был создан с помощью следующего оператора SQL и не существует в таблице:

Select HID, TIME_FROM, nvl(lead(TIME_FROM) over(partition by HID order by TIME_FROM),timestamp '9999-01-01 00:00:00')  LAG_TIME_FROM, TIME_UNTIL
from my_table
where HID in (

' AAAAA12334566 ',
' BBBBBB12334566 ',
' CCCCCC12334566 ',
' DDDDD12334566 ',
'EEEEEEE12334566 ',
'GGGGG12334566 ');

Я хочу обновить столбец TIME_UNTIL с помощью оператора sql, написанного выше (LAG_TIME_FROM). вот моя попытка:

    UPDATE my_table s1
    SET TIME_UNTIL= ( 

    select LAG_TIME_FROM from(
    select HID, TIME_FROM, nvl(lead(TIME_FROM) over(partition by HID order by TIME_FROM),timestamp '9999-01-01 00:00:00')  LAG_TIME_FROM, TIME_UNTIL
    from my_table
    ) s2 
    Where s1.HID in (
    ' AAAAA12334566 ',
    ' BBBBBB12334566 ',
    ' CCCCCC12334566 ',
    ' DDDDD12334566 ',
    'EEEEEEE12334566 ',
    'GGGGG12334566 ')
    and s1. hid = s2. hid
    and s1. TIME_FROM = s2.TIME_FROM
    and s1. TIME_UNTIL = s2. TIME_UNTIL
    );

Но когда я запускаю код, я получаю следующую ошибку:

ORA-01407: невозможно обновить TIME_UNTIL до NULL.

Я не могу понять, почему я получаю NULLS, потому что, когда я запускаю выражение sql:

Select HID, TIME_FROM, nvl(lead(TIME_FROM) over(partition by HID order by TIME_FROM),timestamp '9999-01-01 00:00:00')  LAG_TIME_FROM, TIME_UNTIL
    from my_table
    where HID in (

    ' AAAAA12334566 ',
    ' BBBBBB12334566 ',
    ' CCCCCC12334566 ',
    ' DDDDD12334566 ',
    'EEEEEEE12334566 ',
    'GGGGG12334566 ');

все выглядит отлично

Ответы [ 3 ]

0 голосов
/ 21 октября 2019

Неформатированный, его трудно читать, поэтому я немного его отформатировал.

UPDATE my_table s1
  SET TIME_UNTIL = 
    (select LAG_TIME_FROM 
     from (select HID, 
                  TIME_FROM, 
                  nvl(lead(TIME_FROM) over(partition by HID order by TIME_FROM), 
                      timestamp '9999-01-01 00:00:00'
                     ) LAG_TIME_FROM, 
                     TIME_UNTIL
           from my_table
          ) s2 
     Where s1.HID in (' AAAAA12334566 ',    --> are there really leading and
                      ' BBBBBB12334566 ',   --> trailing spaces here?
                      ' CCCCCC12334566 ',
                      ' DDDDD12334566 ',
                      'EEEEEEE12334566 ',
                      'GGGGG12334566 '
                     )
       and s1. hid = s2. hid                --> there shouldn't be any space between alias and
       and s1. TIME_FROM = s2.TIME_FROM     --> column names
       and s1. TIME_UNTIL = s2. TIME_UNTIL
    );

Есть ли действительно пробелы в начале и в конце элементов IN?

Кроме этого,кажется, что вы хотели обновить только некоторые s1 строки, но ваш запрос обновляет всех из них - некоторые из них до NULL, поэтому Oracle жалуется, поскольку столбец, скорее всего, объявлен как NOT NULL.

Это означает, что вы должны ограничить строки для обновления. Может быть, поможет перемещение предложения IN из подзапроса, например,

UPDATE my_table s1
  SET TIME_UNTIL = 
    (select LAG_TIME_FROM 
     from (select HID, 
                  TIME_FROM, 
                  nvl(lead(TIME_FROM) over(partition by HID order by TIME_FROM), 
                      timestamp '9999-01-01 00:00:00'
                     ) LAG_TIME_FROM, 
                     TIME_UNTIL
           from my_table
          ) s2 
     where 1 = 1                            --> placeholder for now missing IN clause
       and s1.hid = s2. hid                
       and s1.TIME_FROM = s2.TIME_FROM     
       and s1.TIME_UNTIL = s2. TIME_UNTIL
    )
Where s1.HID in (' AAAAA12334566 ',    --> are there really leading and
                 ' BBBBBB12334566 ',   --> trailing spaces here?
                 ' CCCCCC12334566 ',
                 ' DDDDD12334566 ',
                 'EEEEEEE12334566 ',
                 'GGGGG12334566 '
                );

Посмотрите, поможет ли это;если нет, вам придется это исправить. Как? Вы должны знать, у вас есть данные. EXISTS предложение обычно помогает в таких случаях.

0 голосов
/ 21 октября 2019

Переместите nvl() (или, как я предпочитаю, coalesce()) за пределы подзапрос:

UPDATE my_table s1
    SET TIME_UNTIL = coalesce((select LAG_TIME_FROM
                               from (select t.*,
                                            lead(TIME_FROM) over(partition by HID order by TIME_FROM) as LAG_TIME_FROM
                                     from my_table t
                                    ) s2 
                               where s1.hid = s2. hid and
                                     s1.TIME_FROM = s2.TIME_FROM and
                                     s1. TIME_UNTIL = s2.TIME_UNTIL
                              ), timestamp '9999-01-01 00:00:00'
                             )
where s1.HID in (' AAAAA12334566 ',
                 ' BBBBBB12334566 ',
                 ' CCCCCC12334566 ',
                 ' DDDDD12334566 ',
                 'EEEEEEE12334566 ',
                 'GGGGG12334566 '
                );
0 голосов
/ 21 октября 2019

Просто добавьте одно условие после внешнего выбора в операторе обновления

     where LAG_TIME_FROM IS NOT 
    NULL
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...