需要从另一个表的数据中仅更新一个表的每个组的第一行。
我需要使用表B中的详细信息更新表A
Table A
---------
ID Name Date PCNO
1 abc 1/1/12 123
2 def 1/1/12 234
3 fgh 1/2/12 222
4 asd 1/2/12 234
TABLE B
-----------
ID Name Date PCNO
1 adsf 1/1/12 4343
2 sdf 1/2/12 9347
对于按“日期”分组并按PCNO desc排序的表A的每个最高记录,我想更新表B中的值。
我是否为此目的使用等级??
答案 0 :(得分:1)
您可以使用等级或密集等级(甚至行号)来标识“顶部”行,尽管如果实际数据中可能存在联系,则可能不需要考虑怎么做:
select a.id, a.name, a.date_col, a.pcno,
dense_rank() over (partition by date_col order by pcno desc) as rnk
from table_a a;
ID NAME DATE_COL PCNO RNK
---------- ---- ---------- ---------- ----------
2 def 2012-01-01 234 1
1 abc 2012-01-01 123 2
4 asd 2012-01-02 234 1
3 fgh 2012-01-02 222 2
您可以加入表B以获取排名靠前的新值:
select a.id, a.name, a.date_col, a.pcno,
dense_rank() over (partition by a.date_col order by a.pcno desc) as rnk,
case when dense_rank() over (partition by a.date_col order by a.pcno desc) = 1
then b.name else a.name end as new_name,
case when dense_rank() over (partition by a.date_col order by a.pcno desc) = 1
then b.pcno else a.pcno end as new_pcno
from table_a a
join table_b b on b.date_col = a.date_col;
ID NAME DATE_COL PCNO RNK NEW_ NEW_PCNO
---------- ---- ---------- ---------- ---------- ---- ----------
2 def 2012-01-01 234 1 adsf 4343
1 abc 2012-01-01 123 2 abc 123
4 asd 2012-01-02 234 1 sdf 9347
3 fgh 2012-01-02 222 2 fgh 222
然后您可以在合并语句中使用它:
merge into table_a target
using (
select a.id, a.name, a.date_col, a.pcno,
dense_rank() over (partition by a.date_col order by a.pcno desc) as rnk,
case when dense_rank() over (partition by a.date_col order by a.pcno desc) = 1
then b.name else a.name end as new_name,
case when dense_rank() over (partition by a.date_col order by a.pcno desc) = 1
then b.pcno else a.pcno end as new_pcno
from table_a a
join table_b b on b.date_col = a.date_col
) source
on (source.id = target.id)
when matched then update
set target.name = source.new_name, target.pcno = source.new_pcno
where source.rnk = 1;
或者也许
merge into table_a target
using (
select a.id, a.name, a.date_col, a.pcno,
case when dense_rank() over (partition by a.date_col order by a.pcno desc) = 1
then b.name else a.name end as new_name,
case when dense_rank() over (partition by a.date_col order by a.pcno desc) = 1
then b.pcno else a.pcno end as new_pcno
from table_a a
join table_b b on b.date_col = a.date_col
) source
on (source.id = target.id)
when matched then update
set target.name = source.new_name, target.pcno = source.new_pcno
where target.name != source.new_name or target.pcno != source.new_pcno;
其中两个报告2 rows merged
,然后:
select * from table_a;
ID NAME DATE_COL PCNO
---------- ---- ---------- ----------
1 abc 2012-01-01 123
2 adsf 2012-01-01 4343
3 fgh 2012-01-02 222
4 sdf 2012-01-02 9347
如果不总是要匹配一个日期,则可能需要调整它,尽管内部联接应该解决这个问题。