微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

sql – 如何查找由密钥重复但不在所有列重复的行?

我正在使用一个表,它是一组其他表的提取.根据键D1,D2和D3,提取表的所有行都应该是唯一的.他们不是.看来,较早的开发人员尝试通过在此表中查询的所有列中使用SELECT disTINCT来解决此问题.这将会起作用,但是只有当(D1,D2,D3)上的每一行都是非重复列(忽略添加提取表的IDENTITY列)时也是重复的.

换句话说,给定行如下:

D1  D2  D3  C4  C5  C6
=== === === === === ===
A   B   C   X1  X2  X3
A   B   C   X1  X2  X3

然后

SELECT disTINCT D1,D3,C4,C5,C6
FROM BAD_TABLE

将“工作”,因为在(D1,D3)上重复的行之间没有区别.但如果表包含

D1  D2  D3  C4  C5  C6
=== === === === === ===
A   B   C   X1  X2  X3
A   B   C   X1  X2  X4

那么SELECT disTINCT将为键(A,B,C)返回两行.此外,我们必须决定哪个X3或X4是“正确”的值.

我知道如何找到重复的(D1,D3).我甚至知道如何找到所有列(IDENTITY列除外)的重复项:

;
WITH DUPLICATES(D1,D3) AS
(
    SELECT D1,D3
    FROM SOURCE
    GROUP BY D1,D3
    HAVING COUNT(*)>1
)
SELECT S.D1,S.D2,S.D3,S.C4,S.C5,S.C6
FROM SOURCE S
INNER JOIN DUPLICATES D
    ON S.D1 = D.D1 AND S.D2 = D.D2 AND S.D3 = D.D3
ORDER BY S.D1,S.C6

问题是,如何在(D1,D3)上重复上述结果集的子集,但不能在(D1,C6)上重复?

解决方法

你可以通过加入自己的表来做,说D的都是平等的,至少有一个C不相等.
CREATE TABLE #Source (
    D1 VARCHAR(2),D2 VARCHAR(2),D3 VARCHAR(2),C4 VARCHAR(2),C5 VARCHAR(2),C6 VARCHAR(2) );

INSERT INTO #Source VALUES ('A','B','C','X1','X2','X3');
INSERT INTO #Source VALUES ('A','X4');
INSERT INTO #Source VALUES ('A','D','X3');

SELECT S1.D1,S1.D2,S1.D3,S1.C4 C4_1,S2.C4 C4_2,S1.C5 C5_1,S2.C5 C5_2,S1.C6 C6_1,S2.C6 C6_2
FROM
    #Source S1
            INNER JOIN
    #Source S2
            ON
        (       S1.D1 = S2.D1 
            AND S1.D2 = S2.D2
            AND S1.D3 = S2.D3
            AND (   S1.C4 <> S2.C4
                 OR S1.C5 <> S2.C5
                 OR S1.C6 <> S2.C6
                 )
        );

DROP TABLE #Source;

给出以下结果:

D1   D2   D3   C4_1 C4_2 C5_1 C5_2 C6_1 C6_2
---- ---- ---- ---- ---- ---- ---- ---- ----
A    B    C    X1   X1   X2   X2   X4   X3
A    B    C    X1   X1   X2   X2   X3   X4

另请注意,这与MS sql 2000兼容,因为您稍后表示在How to Convert a SQL Query using Common Table Expressions to One Without (for SQL Server 2000)中是必需的.

原文地址:https://www.jb51.cc/mssql/82276.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐