【问题标题】:SQL server: Question about query group and auto idSQL server:关于查询组和自动 ID 的问题
【发布时间】:2020-10-19 06:18:16
【问题描述】:

我有一个像这样有 2 列的表格,图片是输入和输出:

解释输入:2 列是 2 个关系在一起的人。考试:与 B、C、D、H 的关系 输出:我想合并 2 列,列组 ID auto 和列 RelationShip

  • ID 组自动:我尝试查询:row_number() OVER (ORDER BY [columnA]) n
  • RelationShip:将所有人员关系组合在一起并将它们分组到 1 个 ID 组。考试人员 A、B、C、D、H 共同发运,组 id auto 为 1

我在https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=f81ff386b07589654ad133a8e4b30472有一个演示

在我的查询中,首先我将数据变成单列,其次我计算字母,下一步我不知道查询。

我尝试了递归 CTE 但出错(也许我对递归不太了解)

我想在sql查询中解决这个问题。

【问题讨论】:

    标签: sql sql-server recursion merge


    【解决方案1】:

    您可以使用递归 CTE 为每个“列”值分配一个数字。首先在两个方向上创建边缘,然后跟随它们:

    with pairs as (
          select columnA, columnB from myTable
          union -- on purpose to remove duplicates
          select columnB, columnA from myTable
         ),
         cte as (
          select distinct columnA, columnA as columnB,
                 convert(varchar(max), ',' + columnA + ',') as visited,
                 1 as lev
          from pairs
          union all
          select cte.columnA, p.columnB, concat(visited, p.columnA, ','), lev + 1
          from cte join
               pairs p
               on cte.columnB = p.columnA
          where cte.visited not like concat('%,', p.columnB, ',%') and
                lev < 5
         )
    select cte.columnA, min(cte.columnB),
           dense_rank() over (order by min(cte.columnB))
    from cte
    group by cte.columnA;
    

    然后您可以加入其中以分配组 ID:

    with pairs as (
          select columnA, columnB from myTable
          union -- on purpose to remove duplicates
          select columnB, columnA from myTable
         ),
         cte as (
          select distinct columnA, columnA as columnB,
                 convert(varchar(max), ',' + columnA + ',') as visited,
                 1 as lev
          from pairs
          union all
          select cte.columnA, p.columnB, concat(visited, p.columnA, ','), lev + 1
          from cte join
               pairs p
               on cte.columnB = p.columnA
          where cte.visited not like concat('%,', p.columnB, ',%') and
                lev < 5
         ),
         groups as (
          select cte.columnA, min(cte.columnB) as min_columnB,
                 dense_rank() over (order by min(cte.columnB)) as group_id
          from cte
          group by cte.columnA
         )
    select t.*, g.group_id
    from mytable t join
         groups g
         on g.columnA = t.columnA;
    

    Here 是一个 dbfiddle。

    【讨论】:

    • 求你的帮助,查询 1 比查询 2 好
    • @DanhTranQuoc 。 . .第二个查询扩展了第一个。第一个将group_id 分配给各个值。第二个是原始数据中的对。
    猜你喜欢
    • 1970-01-01
    • 2013-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多