我有两个相同的表:user_id,name,age,date_added。 USER_ID列可能包含多个重复的ID。
需要使用以下条件将这两个表合并为1。 如果同一用户有多个具有相同“名称”的记录,则需要仅保留LATEST(by date_added)记录。 此脚本将与MSSQL 2005一起使用,但如果有人提出不使用ROW_NUMBER()的版本,也会感激不尽。需要此脚本重新加载一个损坏的表,性能并不重要。
示例:
表1:
1,'john',21,01/01/2010
1,'john',15,01/01/2005
1,'john',71,01/01/2001
表2:
1,'john',81,01/01/2007
1,'john',15,01/01/2005
1,'john',11,01/01/2008
结果:
1,'john',21,01/01/2010
更新: 我想我找到了自己的解决方案。这是基于Larry Lustig和Joe Stefanelli先前提出的问题的答案。
以tmp2为
(
SELECT * FROM table1
UNION
SELECT * FROM table2
)
SELECT * FROM tmp2 c1 WHERE(SELECT COUNT(*)FROM tmp2 c2 WHERE c2.user_id = c1.user_id AND c2.name = c1.name AND c2.date_added> = c1.date_added)< = 1
请问您能否将此查询转换为没有'WITH'子句的查询?
答案 0 :(得分:0)
您可以使用not exists
,例如:
; with all_users as
(
select *
from table1 u1
union all
select *
from table2 u2
)
select *
from all_users u1
where not exists
(
select *
from all_users u2
where u1.name = u2.name
and u1.record_time < u2.record_time
)
如果数据库不支持CTE,请在使用它的两个地方展开all_users
。
P.S。如果只有三列,而不是更多,您可以使用更简单的解决方案:
select name
, MAX(record_time)
from (
select *
from table1 u1
union all
select *
from table2 u2
) sub
group by
name
答案 1 :(得分:0)
以下是@Andomar答案的变体:
; with all_users as
(
select *
from table1 u1
union all
select *
from table2 u2
)
, ranker as (
select *,
rank() over (partition by userid order by recordtime) as [r]
)
select * from ranker where [r] = 1
答案 2 :(得分:0)
只是为了提供不同的方法......
WITH distinctlist
As (SELECT user_id,
name
FROM table1
UNION
SELECT user_id,
name
FROM table2)
SELECT C.*
FROM distinctlist d
CROSS APPLY (SELECT TOP 1 *
FROM (SELECT TOP 1 *
FROM table1
WHERE user_id = d.user_id
AND name = d.name
ORDER BY date_added DESC
UNION ALL
SELECT TOP 1 *
FROM table1
WHERE user_id = d.user_id
AND name = d.name
ORDER BY date_added DESC) T
ORDER BY date_added DESC) C