如何将具有相同ID
的多行合并为一行。
当同一列中的第一行和第二行中的值相同或第一行中有值且第二行中有NULL
时。
当同一列中第一行和第二行的值不同时,我不想合并。
我有桌子:
ID |A |B |C
1 NULL 31 NULL
1 412 NULL 1
2 567 38 4
2 567 NULL NULL
3 2 NULL NULL
3 5 NULL NULL
4 6 1 NULL
4 8 NULL 5
4 NULL NULL 5
我想得到表:
ID |A |B |C
1 412 31 1
2 567 38 4
3 2 NULL NULL
3 5 NULL NULL
4 6 1 NULL
4 8 NULL 5
4 NULL NULL 5
答案 0 :(得分:6)
我认为上述答案的解决方案更简单(这也是正确的)。它基本上获取可以在CTE中合并的合并值,然后将其与不能合并的数据合并。
WITH CTE AS (
SELECT
ID,
MAX(A) AS A,
MAX(B) AS B,
MAX(C) AS C
FROM dbo.Records
GROUP BY ID
HAVING MAX(A) = MIN(A)
AND MAX(B) = MIN(B)
AND MAX(C) = MIN(C)
)
SELECT *
FROM CTE
UNION ALL
SELECT *
FROM dbo.Records
WHERE ID NOT IN (SELECT ID FROM CTE)
答案 1 :(得分:3)
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
创建所有可合并行来实现 - 对于ID
中的每个列应该相同,并且有用地排除{{1} s - 然后将表中无法合并的所有行追加到此列表中。 NULL
的特殊提示允许列具有EXISTS ... INTERSECT
的所有NULL
值(因此ID
和Min
为{{1}并且不能相等)。也就是说,它的功能类似Max
,但允许NULL
s进行比较。
这是一个稍微不同(早期)的解决方案,我给出了可能提供不同的性能特征,并且更复杂,我喜欢更少,但是是一个流动的查询(没有Min(A) = Max(A) AND Min(B) = Max(B) AND Min(C) = Max(C)
)我更喜欢,太
NULL
这也是上面的SQL Fiddle。
这使用与第一个查询类似的逻辑来计算是否应该合并一个组,然后使用它来创建一个分组键,该键对于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
;
。使用最终ID
(ID
也可以工作)应该合并的行被合并,因为它们共享一个分组键,而不应该合并的行不是因为它们有Min
上的不同分组键。
根据您的数据集,索引,表大小和其他性能因素,这些查询中的任何一个都可能执行得更好,但第二个查询有一些工作要做,以便用两种排序而不是一种排序。
答案 2 :(得分:0)
您可以尝试这样的事情:
select
isnull(t1.A, t2.A) as A,
isnull(t1.B, t2.B) as B,
isnull(t1.C, t2.C) as C
from
table_name t1
join table_name t2 on t1.ID = t2.ID and .....
你提到了第一和第二的概念。怎么办
你定义这个订单?下订单定义条件
在这里:.....
另外,我假设每个ID值只有2行。