【问题标题】:SQL How to group by two different columns that contain the same dataSQL如何按包含相同数据的两个不同列进行分组
【发布时间】:2019-05-11 02:42:33
【问题描述】:

如何将以下数据组合在一起。
请注意,相同的数据可以在不同的列中,也可以在同一列中。

|身份证 |手机 |主页 | | 1 |空 | 626... | | 2 | 626... |空 | | 3 | 405... |空 | | 4 |空 | 405... | | 5 | 626... | 405... | | 6 | 405... | 626... |

这样它会产生这个结果

|组ID |身份证 | | 1 | 1 | | 1 | 2 | | 1 | 5 | | 1 | 6 | | 2 | 3 | | 2 | 4 | | 2 | 5 | | 2 | 6 |


GroupId 可以是随机生成的 ID,例如。 NEWID(),它用于识别不同列之间的“重复”
Null 值被忽略。

【问题讨论】:

  • 什么是 GroupId?解释用于获取该输出的逻辑
  • 我认为你必须更清楚你在这里想要做什么。看了太久,我有点明白你想要做什么,但你需要给出一个更好的数据示例。
  • 如果两个值都不是NULL怎么办?
  • @JoakimDanielson 我稍微更新了问题,希望更清楚一点
  • @wavery 这个想法几乎是将所有重复的电话号码组合在一起,不管它在哪一列

标签: sql sql-server tsql


【解决方案1】:

执行基表的两个projectionsUNION ALL。在这些预测中,分别排除了在 MOBILEHOME 列中包含 NULL 的行。然后将DENSE_RANK 函数应用于结果集。

WITH
  t AS (
    SELECT * 
    FROM (
      VALUES(1, NULL, 626456),
      (2, 626456, NULL),
      (3, 405123, NULL),
      (4, NULL, 405123),
      (5, 626456, 405123),
      (6, 405123, 626456)
    ) AS t (id, mobile, home)
  ),
  u AS (
    SELECT id, mobile AS dr FROM t WHERE mobile IS NOT NULL
    UNION ALL
    SELECT id, home FROM t WHERE home IS NOT NULL
  )
SELECT
  DENSE_RANK() OVER(ORDER BY dr DESC) AS GroupId, Id
FROM u
ORDER BY GroupId, Id;

输出:

+---------+----+
| GroupId | Id |
+---------+----+
|       1 |  1 |
|       1 |  2 |
|       1 |  5 |
|       1 |  6 |
|       2 |  3 |
|       2 |  4 |
|       2 |  5 |
|       2 |  6 |
+---------+----+

【讨论】:

    【解决方案2】:

    我猜,您需要 COALESCEMobileHome 值返回非空值,并根据结果对文本进行分组并创建 GroupId

    所以你可以申请COALESCE(Mobile, Home)DENSE_RANK() OVER (ORDER BY

    请找到带有示例数据的演示:

    DECLARE @TestTable TABLE (Id INT, Mobile INT, Home INT);
    
    INSERT INTO @TestTable (Id, Mobile, Home) VALUES
    (1, NULL, 626456),
    (2, 626456, NULL),
    (3, 405123, NULL),
    (4, NULL, 405123);
    
    SELECT DENSE_RANK() OVER(ORDER BY COALESCE(Mobile, Home)) AS GroupId,
           Id
    FROM @TestTable
    ORDER BY Id
    

    这里我使用ORDER BY 基于COALESCE 结果,您可以根据您的业务需要更改它。

    Demo on db <> fiddle

    【讨论】:

    • COALESCE() 不会“连接”值。我知道英语可能不是你的母语,但你的说法很有误导性。
    • @Arulkumar 感谢您抽出宝贵的时间来解决这个问题,我又更新了两行数据,这会产生不希望的结果
    • @AllenChen 你能分享更新的小提琴链接吗?每次执行时,小提琴链接都会改变,
    • @AllenChen 如果您有更多对理解问题至关重要的示例数据,然后将它们和预期输出添加到您的问题中
    【解决方案3】:

    抱歉,我发现很难解释我试图完成的工作。如果有人遇到这种情况,请看看这是否是一个潜在的解决方案

    ; 与 CTE 作为 ( 选择 * 从 ( 值(1,NULL,626456), (2, 626456, 空), (3, 405123, 空), (4, 空, 405123), (5, 626456, 405123), (6, 405123, 626456)) AS tbl (id, mobile, home) ), 枢轴 AS ( 选择不同的 pvt.value 来自 CTE CROSS APPLY (VALUES('mobile', mobile), ('home', home)) AS pvt (phone, value) ) SELECT DENSE_RANK() OVER (ORDER BY p.value) as gid, c.id 从 CTE c INNER JOIN PivotCte p ON c.mobile = p.value OR c.home = p.value

    DB Fiddle

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-07
      • 2014-02-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多