在SQL中有一种模拟SAS MERGE操作的方法

时间:2018-01-25 00:43:27

标签: sql-server tsql

假设我有以下2个数据集:

A           B           C
----------- ----------- -----------
1           100         1000
1           120         1001
2           140         1002
2           160         1003
3           180         1004
3           190         1005
3           200         1006

A           D           E
----------- ----------- -----------
1           61          2000
1           62          2001
1           63          2001
2           64          2002
3           65          2004
3           66          2005
3           67          2006
3           68          2006

是否可以生成以下输出数据集(。表示null)?

A           B           C           D           E
----------- ----------- ----------- ----------- -----------
1           100         1000        61          2000
1           120         1001        62          2001
1           .           .           63          2001
2           140         1002        64          2002
2           160         1003        .           .
3           180         1004        65          2004
3           190         1005        66          2005
3           200         1006        67          2006
3           .           .           68          2006

合并将从两个表中获取所有记录,并将它们最多添加到结果集一次。

如果记录加入,则它们不会像传统的sql连接那样相乘。每条记录都与匹配的记录对齐,当它们用完记录时,会插入null。

我一直在想,也许新的分区功能可以实现这一点,但是我现在已经远离SQL太长时间了,我想不出一种方法来做这个“特殊连接”。

我还考虑制作一个不同的密钥列表,然后将它们连接到2个表,但后来我卡住了,因为连接仍然会使记录计数倍增。

1 个答案:

答案 0 :(得分:2)

您可以使用row_number()窗口功能执行此操作。命名两个数据集DS1DS2,结果将如下所示:

WITH DS1Seq As (
    SELECT A, B, C, row_number() OVER (partition by A order by A, B, C) As SeqNumber 
    FROM DS1
),
DS2Seq As (
    SELECT A, D, E, row_number() OVER (partition by A order by A, D, E) As SeqNumber
    FROM DS2
)
SELECT coalesce(DS1Seq.A, DS2Seq.A) As A, B, C, D, E
FROM DS1Seq
FULL JOIN DS2Seq on DS1Seq.A = DS2Seq.A AND DS1Seq.SeqNumber = DS2Seq.SeqNumber