SQL:如何成对查找重复项

时间:2017-11-28 18:37:37

标签: sql sql-server tsql

我想根据Qualifier_id列查找具有相同客户编号和结束日期的记录。 Qualifier_ID 1和4,2和5,3和6是成对的。 我想得到以下结果:

>     ID Client NO. Qualifier_ID    End Date    R
>     1   10475       1           12/31/9998    1
>     2   10475       4           12/31/9998    2
>     3   10475       2           12/31/9998    1
>     4   10475       5           12/31/9998    2
>     5   10475       3           12/31/9998    1
>     6   10475       6           12/31/9998    2

我在下面编写了SQL,但它不起作用:

SELECT *,ROW_NUMBER() OVER (PARTITION BY [Client No],QUALIFIER_ID ORDER BY [Client No]) R
FROM Table 
WHERE [END DATE]='9998-12-31 00:00:00.000'

2 个答案:

答案 0 :(得分:2)

你声明你

  

想要查找具有相同客户编号和结束日期的记录

但是您按客户编号和限定符ID(不是结束日期)进行分区。

我首先将您的PARTITION BY更改为:

PARTITION BY [Client No.], [End Date]

听起来你只知道那个1和4; 2和5; 3和6总是配对在一起。您可以构建一个地图,为这些限定符提供一个组号,加入它,然后将其包含在PARTITION BY中。

例如:

WITH MagicGroupings (QualifierId, GroupNumber) AS
(
    SELECT 1, 1 UNION ALL
    SELECT 4, 1 UNION ALL
    SELECT 2, 2 UNION ALL
    SELECT 5, 2 UNION ALL
    SELECT 3, 3 UNION ALL
    SELECT 6, 3

)
,TestData(ID, ClientNo, Qualifier_ID, EndDate) AS
(
    SELECT 1, '10475', 1, '12/31/9998' UNION ALL
    SELECT 2, '10475', 4, '12/31/9998' UNION ALL
    SELECT 3, '10475', 2, '12/31/9998' UNION ALL
    SELECT 4, '10475', 5, '12/31/9998' UNION ALL
    SELECT 5, '10475', 3, '12/31/9998' UNION ALL
    SELECT 6, '10475', 6, '12/31/9998'
)
SELECT 
    td.*,
    ROW_NUMBER() OVER (PARTITION BY [ClientNo], [EndDate], mg.[GroupNumber] ORDER BY ClientNo) R
FROM 
    TestData td
JOIN
    MagicGroupings mg
    ON
    td.Qualifier_ID = mg.QualifierId
WHERE 
    [EndDate] = '12/31/9998'

会给你:

ID          ClientNo Qualifier_ID EndDate    R
----------- -------- ------------ ---------- --------------------
2           10475    4            12/31/9998 1
1           10475    1            12/31/9998 2
4           10475    5            12/31/9998 1
3           10475    2            12/31/9998 2
6           10475    6            12/31/9998 1
5           10475    3            12/31/9998 2

顺便说一下,您可以通过提供JOIN中的值来消除第一个CTE:

WITH TestData(ID, ClientNo, Qualifier_ID, EndDate) AS
(
    SELECT 1, '10475', 1, '12/31/9998' UNION ALL
    SELECT 2, '10475', 4, '12/31/9998' UNION ALL
    SELECT 3, '10475', 2, '12/31/9998' UNION ALL
    SELECT 4, '10475', 5, '12/31/9998' UNION ALL
    SELECT 5, '10475', 3, '12/31/9998' UNION ALL
    SELECT 6, '10475', 6, '12/31/9998'
)
SELECT 
    td.*,
    ROW_NUMBER() OVER (PARTITION BY [ClientNo], [EndDate], mg.[GroupNumber] ORDER BY ClientNo) R
FROM 
    TestData td
JOIN
    (VALUES (1, 1), (4, 1), (2, 2), (5, 2), (3, 3), (6, 3)) mg(QualifierId, GroupNumber)
    ON
    td.Qualifier_ID = mg.QualifierId
WHERE 
    [EndDate] = '12/31/9998'

答案 1 :(得分:1)

如果我理解正确,您需要order by Qualifier_ID来计算r

SELECT t.*,
       ROW_NUMBER() OVER (PARTITION BY [Client No]
                          ORDER BY Qualifier_ID
                        ) as r
FROM Table t
WHERE [END DATE] = '9998-12-31';

您可能希望在[END DATE]中加入PARTITION BY,但因为您要过滤到单个日期,所以这不是必需的。