I have the following structure of my table:
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
Column HID
, TIME_FROM
and TIME_UNTIL
exist in my table. The column LAG_TIME_FROM
was generated by the following SQL statement and doesn't exist in the table:
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 ');
What I want to do is to update TIME_UNTIL column by the sql statement written above(LAG_TIME_FROM). here is my attempt:
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
);
But when I run the code I get the following error:
ORA-01407: cannot update TIME_UNTIL to NULL.
I cannot understand why do I get NULLS, because when I run sql statement:
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 ');
everything looks perfectly fine
Just add one condition after your outer select in update statement
where LAG_TIME_FROM IS NOT
NULL
Unformated, it is difficult to read so I formatted it a little bit.
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
);
Are there really leading and trailing spaces in IN
elements?
Other than that, it seems that you wanted to update only some s1
rows, but your query is updating all of them - some of them to NULL
so Oracle complains as column is most probably declared as NOT NULL
.
It means that you have to restrict rows to be updated. Maybe moving IN
clause out of subquery will help, eg
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 '
);
See if it helps; if not, you'll have to fix it. How? You should know, you have the data. EXISTS
clause usually helps in such cases.
Move the nvl()
(or as I prefer, coalesce()
) outside the subquery:
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 '
);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.