【问题标题】:Merge multiple rows in SQL with tie breaking on primary key合并 SQL 中的多行,并在主键上打破平局
【发布时间】:2016-05-12 03:41:27
【问题描述】:

我有一个表格,其中包含如下数据

key | A | B    | C
---------------------------
 1  | x | 0    | 1
 2  | x | 2    | 0
 3  | x | NULL | 4
 4  | y | 7    | 1
 5  | y | 3    | NULL
 6  | z | NULL | 4

我想根据 A 列将行合并在一起,其中最大的主键是非 NULL 值之间的“决胜局”

Result
key | A | B    | C
---------------------------
 1  | x | 2    | 4
 2  | y | 3    | 1
 3  | z | NULL | 4

假设我的数据实际上是 40 列和 100 万行且重复程度未知,那么实现此目标的最佳方法是什么?

【问题讨论】:

    标签: sql sql-server merge duplicates


    【解决方案1】:

    使用ROW_NUMBER 和条件聚合:

    SQL Fiddle

    WITH cte AS(
        SELECT *,
            rnB = ROW_NUMBER() OVER(PARTITION BY A ORDER BY CASE WHEN B IS NULL THEN 0 ELSE 1 END DESC, [key] DESC),
            rnC = ROW_NUMBER() OVER(PARTITION BY A ORDER BY CASE WHEN C IS NULL THEN 0 ELSE 1 END DESC, [key] DESC)
        FROM tbl
    )
    SELECT
        [key] = ROW_NUMBER() OVER(ORDER BY A),
        A,
        B = MAX(CASE WHEN rnB = 1 THEN B END),
        C = MAX(CASE WHEN rnC = 1 THEN C END)
    FROM cte
    GROUP BY A
    

    【讨论】:

    • 作为对此的一个小扩展,如果 A 是 2 列(名字,姓氏),它将如何工作?
    • 只需将任何出现的A 替换为FirstName,LastName
    • 我刚刚遇到了另一个小问题。我希望保留与每条记录关联的最大 [key] 值。 (x=3, y=5, z=6)。我试图尝试 [key] = MAX([key]) OVER(PARTITION BY concat(First, Last)),但这给了我错误
    猜你喜欢
    • 2013-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-23
    • 1970-01-01
    • 2023-01-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多