WITH Collapsed AS (
SELECT
ID,
A = Min(A),
B = Min(B),
C = Min(C)
FROM
dbo.MyTable
GROUP BY
ID
HAVING
EXISTS (
SELECT Min(A), Min(B), Min(C)
INTERSECT
SELECT Max(A), Max(B), Max(C)
)
)
SELECT
*
FROM
Collapsed
UNION ALL
SELECT
*
FROM
dbo.MyTable T
WHERE
NOT EXISTS (
SELECT *
FROM Collapsed C
WHERE T.ID = C.ID
);
Это работает, создавая все объединяемые строки посредством использования Min
и Max
--which должны быть одинаковыми для каждого столбца в пределах ID
и которые целесообразно исключить NULL
с - затем добавления в этот список перечислены все строки из таблицы, которые не могут быть объединены. Специальный трюк с EXISTS ... INTERSECT
допускает случай, когда столбец имеет все значения NULL
для ID
(и, таким образом, Min
и - NULL
и не могут равняться друг другу). То есть, он функционирует как Min(A) = Max(A) AND Min(B) = Max(B) AND Min(C) = Max(C)
, но позволяет NULL
s для сравнения.
Это немного другое (ранее) решение, которое я дал, которое может предлагать различные характеристики производительности, и быть более сложным, мне нравится меньше, но, будучи единственным текущим запросом (без UNION
), я вроде как больше.
WITH Collapsible AS (
SELECT
ID
FROM
dbo.MyTable
GROUP BY
ID
HAVING
EXISTS (
SELECT Min(A), Min(B), Min(C)
INTERSECT
SELECT Max(A), Max(B), Max(C)
)
), Calc AS (
SELECT
T.*,
Grp = Coalesce(C.ID, Row_Number() OVER (PARTITION BY T.ID ORDER BY (SELECT 1)))
FROM
dbo.MyTable T
LEFT JOIN Collapsible C
ON T.ID = C.ID
)
SELECT
ID,
A = Min(A),
B = Min(B),
C = Min(C)
FROM
Calc
GROUP BY
ID,
Grp
;
Это также в вышеупомянутом скрипте SQL.
Это использует подобную логику первого запроса, чтобы вычислить, должна ли быть объединена группа, а затем использует это, чтобы создать ключ группировки, которая либо одинаковы для всех строк в пределах ID
или различно для всех строк в пределах ID
. С окончательным Min
(будет работать так же хорошо), строки, которые должны быть объединены, объединяются, потому что они разделяют ключ группировки, а строки, которые не должны объединяться, не потому, что у них есть отдельные ключи группировки по ID
.
В зависимости от вашего набора данных, индексов, размера таблицы и других факторов производительности любой из этих запросов может работать лучше, хотя второй запрос выполняет некоторую работу, чтобы догнать, с двумя типами вместо одного.
что вы пробовали? Что произойдет, если у вас более двух строк с разными данными в двух строках? Как вы выбираете, какую строку взять данные из другого? – Kritner
Почему в вашем желаемом результате вы сохраняете последнюю строку ('4 NULL NULL 5')? Не следует ли слиться с предыдущей строкой ('4 8 NULL 5')? –
@VladimirBaranov Нет, его не следует сливать из-за строки ('4 6 1 NULL'), имеющей конфликт во втором значении' 6' с '8' в следующей строке. Согласно приведенному объяснению, никакие строки для этого идентификатора не должны быть объединены. – ErikE