У меня проблема с перечислением дублированных строк, содержащих столбцы 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
Теперь я хочу показать все строки, дублирующие другие строки, я использую следующий запрос.
SELECT a, b
FROM dbo.t
GROUP
BY a, b
HAVING count(*) > 1
, который даст нам результат:
a b
-------- --------
NULL NULL
a b
c d
Теперь, если я хочу перечислить все строки, которые вносят вклад в дублирование, я использую этот запрос:
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)
Что даст мне результат:
a b
-------- --------
a b
a b
a b
c d
c d
c d
c d
Как видите, все строки, содержащие NULL, фильтруются. Причина, по которой я подумал, заключается в том, что я использую знак равенства для проверки условия (dbo.t.a = duplicate.a AND dbo.t.b = duplicate.b), и значения NULL нельзя сравнивать с использованием знака равенства. Итак, чтобы включить строки с пустыми значениями в последнем результате, я изменил вышеупомянутый запрос на
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)
И этот запрос даст мне ответ, как я хотел:
a b
-------- --------
NULL NULL
NULL NULL
NULL NULL
NULL NULL
a b
a b
a b
c d
c d
c d
c d
Теперь мой вопрос, как вы можете видеть, состоит в том, что этот запрос включает в себя только два столбца. Чтобы включить NULL в последний результат, вам нужно использовать в запросе много операторов проверки условий. По мере того как число столбцов увеличивается, операторы проверки условий, которые вам нужны в вашем запросе, удивительно увеличиваются. Как я могу решить эту проблему?
Большое спасибо.