我在Oracle 11 G上运行它 我试图使用TABLE2.CLASSNAME中的值更新TABLE1中的列CLASS。 用于JOIN的键是TABLE1.T1ID = TABLE2.T2ID TABLE2可以具有相同ID的多个CLASSNAME值。
可用于更新的列是:
表1:
TID - Identifier
LOADDT - Date all records were loaded
表2:
T2ID - Identifier
LOADDT - Date all records were loaded
ENROLLDATE - A date updated when the student enrolled in the class. The latest date will have the most recent class he enrolled in.
这是我的UPDATE语句:
UPDATE table1 fs
SET class =
(SELECT a.classname
FROM table2 a
WHERE TRIM (a.t2id) = TRIM (fs.t1id)
AND TO_DATE (a.loaddt, 'DD-MON-YY') =
TO_DATE ( (SELECT MAX (loaddt)
FROM table2 aa
WHERE TRIM (a.t2id) = TRIM (aa.t2id)),
'DD-MON-YY' AND ROWNUM = 1)
AND ROWNUM = 1)
WHERE TO_DATE (loaddt, 'DD-MON-YY') =
TO_DATE ( (SELECT MAX (loaddt) FROM table1), 'DD-MON-YY');
即使TABLE2.CLASSNAME没有NULL,我的更新似乎也会留下很多行NULL(90%)。
我的更新中没有使用ENROLLDATE。
我错过了什么吗?你能帮忙吗?
答案 0 :(得分:1)
UPDATE TABLE1 fs
SET CLASS=
(
select a.CLASSNAME from (
select T2ID, LOADDT, CLASSNAME,
row_number() over(partition by T2ID order by LOADDT desc) rw
from TABLE2) a
where a.rw = 1 and TRIM(a.T2ID) = TRIM(fs.T1ID)
)
-- do you really need this condition?
WHERE TO_DATE(LOADDT,'DD-MON-YY')=TO_DATE((SELECT MAX(LOADDT) FROM TABLE1),'DD-MON-YY');
答案 1 :(得分:1)
ROWNUM = 1
几乎总是可以翻译为“选择准随机行”。在许多情况下(比如你的),你使用分析查询要好得多,如果没有其他原因,那么它们不容易出错。
这个答案基于@ Multisync的解决方案,但我不喜欢在SET
子句中使用子查询。更新相关行时,我更喜欢MERGE
:
MERGE INTO table1 fs
USING (SELECT classname, t2id
FROM (SELECT t2id,
classname,
ROW_NUMBER ()
OVER (PARTITION BY t2id ORDER BY loaddt DESC)
rw
FROM table2) a
WHERE a.rw = 1) b
ON (TRIM (b.t2id) = TRIM (fs.t1id))
WHEN MATCHED THEN
UPDATE SET
class = b.classname
WHERE TO_DATE (loaddt, 'DD-MON-YY') =
TO_DATE ( (SELECT MAX (loaddt) FROM table1), 'DD-MON-YY');