Другие опции:
DECLARE @myTable AS TABLE (Title CHAR(4) NOT NULL, Value INT NULL);
INSERT INTO @myTable (Title, Value)
VALUES ('ex1', 8)
, ('ex1', 9)
, ('ex1', NULL)
, ('ex2', 8)
, ('ex2', NULL)
, ('ex3', NULL);
-- Original
SELECT DISTINCT
T1.Title
, T2.Value
FROM @myTable T1
LEFT JOIN @myTable T2 ON T2.Title = T1.Title
AND T2.Value IS NOT NULL;
-- Common Table Expression example
WITH cte AS
(SELECT *
, ROW_NUMBER() OVER (PARTITION BY Title
ORDER BY Value DESC) RN
FROM @myTable)
SELECT cte.Title
, cte.Value
FROM cte
WHERE RN = 1
OR cte.Value IS NOT NULL
Если вы пробегаете общее табличное выражение и присваиваете номера строк, вы можете обеспечить по крайней мере одну строку для каждого «Заголовка» без нескольких обращений к таблице. Если вы запускаете планы выполнения с двух сторон, я вижу сохранение в версии cte по сравнению с объединением. Будет зависеть от того, сколько данных входит, хотя сортировка может стать более дорогой, чем объединение, хотя для версии объединения требуется сортировка для различных типов.
Дайте им попробовать реальные данные и получите немного времени. дайте мне знать, если это поможет.