SQL查询合并2个表与附加条件?

时间:2011-01-13 14:36:55

标签: sql sql-server

我有两个相同的表: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'子句的查询?

3 个答案:

答案 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