J'ai un problème de liste des lignes dupliquées qui incluent des colonnes NULL. Lemme montre mon problème en premier.Comment lister toutes les lignes dupliquées qui peuvent inclure des colonnes NULL?
USE [tempdb];
GO
IF OBJECT_ID(N'dbo.t') IS NOT NULL
BEGIN
DROP TABLE dbo.t
END
GO
CREATE TABLE dbo.t
(
a NVARCHAR(8),
b NVARCHAR(8)
);
GO
INSERT t VALUES ('a', 'b');
INSERT t VALUES ('a', 'b');
INSERT t VALUES ('a', 'b');
INSERT t VALUES ('c', 'd');
INSERT t VALUES ('c', 'd');
INSERT t VALUES ('c', 'd');
INSERT t VALUES ('c', 'd');
INSERT t VALUES ('e', NULL);
INSERT t VALUES (NULL, NULL);
INSERT t VALUES (NULL, NULL);
INSERT t VALUES (NULL, NULL);
INSERT t VALUES (NULL, NULL);
GO
Maintenant, je veux afficher toutes les lignes qui ont d'autres lignes dupliquées avec eux, j'utilise la requête suivante.
SELECT a, b
FROM dbo.t
GROUP
BY a, b
HAVING count(*) > 1
qui nous donnera le résultat:
a b
-------- --------
NULL NULL
a b
c d
Maintenant, si je veux énumérer toutes les lignes qui apportent une contribution à la duplication, j'utilise cette requête:
WITH
duplicate (a, b) AS
(
SELECT a, b
FROM dbo.t
GROUP
BY a, b
HAVING count(*) > 1
)
SELECT dbo.t.a, dbo.t.b
FROM dbo.t
INNER JOIN duplicate
ON (dbo.t.a = duplicate.a
AND dbo.t.b = duplicate.b)
qui donnera moi le résultat:
a b
-------- --------
a b
a b
a b
c d
c d
c d
c d
Comme vous pouvez le voir, toutes les lignes incluent les valeurs NULL sont filtrées. La raison pour laquelle je pensais est que j'utilise le signe égal pour tester la condition (dbo.t.a = duplicate.a ET dbo.t.b = duplicate.b), et que les valeurs NULL ne peuvent pas être comparées utilisent un signe égal. Ainsi, afin d'inclure les lignes qui incluent NULLs en elle dans le dernier résultat, je modifier la requête précitée à
WITH
duplicate (a, b) AS
(
SELECT a, b
FROM dbo.t
GROUP
BY a, b
HAVING count(*) > 1
)
SELECT dbo.t.a, dbo.t.b
FROM dbo.t
INNER JOIN duplicate
ON (dbo.t.a = duplicate.a
AND dbo.t.b = duplicate.b)
OR
(dbo.t.a IS NULL
AND duplicate.a IS NULL
AND dbo.t.b = duplicate.b)
OR
(dbo.t.b IS NULL
AND duplicate.b IS NULL
AND dbo.t.a = duplicate.a)
OR
(dbo.t.a IS NULL
AND duplicate.a IS NULL
AND dbo.t.b IS NULL
AND duplicate.b IS NULL)
Et cette requête me donnera la réponse que je voulais:
a b
-------- --------
NULL NULL
NULL NULL
NULL NULL
NULL NULL
a b
a b
a b
c d
c d
c d
c d
Maintenant, ma question est, comme vous pouvez le voir, cette requête ne comprend que deux colonnes, afin d'inclure des valeurs nulles dans le dernier résultat, vous devez utiliser plusieurs instructions de test de condition dans la requête. À mesure que le nombre de colonnes augmente, les instructions de test de condition dont vous avez besoin dans votre requête augmentent de façon étonnante. Comment puis-je résoudre ce problème?
Merci beaucoup.