【问题标题】:SQL query for column threaded relationship列线程关系的 SQL 查询
【发布时间】:2013-11-07 14:56:30
【问题描述】:

这是表格的简化视图。抱歉,我无法保存这张桌子的照片,所以希望没问题。

c1___c2
1____a
1____b
2____a
2____b
2____c
2____d
3____e
3____a
4____z
5____d

结果是由于C2列的关系, 第 1 组将包括 1、2、3、5(因为它们具有重叠的 c2 值,基本上说明 a=b=c=d=e) 第 2 组将包括 4

我有数百万行包含此类数据,目前有一个游标作业运行 x 次来构建这些组。我能够想象这应该如何工作,但我无法构建一个可以提取这种关系的查询。 有什么建议么? 谢谢

【问题讨论】:

  • 这种类型的操作相当复杂,可能需要诸如临时表和循环或递归 cte 之类的东西来生成所有组。为什么要将光标作业压缩为单个查询?
  • 我可以在这里填写所有组:sqlfiddle.com/#!3/cf29c/5。将其转换为组集更加复杂,但应该可以使用另一个临时表和循环。
  • 感谢您的 cmets。选择不同的路线有两个原因。 1. 运行需要一个多小时, 2. 我们创建了一个 x 重复的光标代码块,而不是 do while 循环。意思是,我们将“光标代码”写了 3 次,如果我们在多个组中找到一个字母,那么我们添加另一个重复的光标代码块。我认为找出一种循环匹配功能直到匹配完成的方法会更有效。不过,您为我提供了一些额外的想法。谢谢。

标签: sql tsql


【解决方案1】:

在 SQL Server 2012 上测试:

WITH t AS (
    SELECT
        t.c1,
        t.c2,
        tm.c1_min
    FROM
        Test t
    JOIN
        (
            SELECT
                c2,
                MIN(c1) AS c1_min
            FROM
                Test
            GROUP BY
                c2
        ) AS tm
    ON
        t.c2 = tm.c2
),
rt AS (
    SELECT
        c1_min,
        c1,
        1 AS cnt
    FROM
        t
UNION ALL
    SELECT
        rt.c1_min,
        t.c1,
        rt.cnt + 1 AS cnt
    FROM
        rt
    JOIN
        t
    ON
        rt.c1 = t.c1_min
    AND
        rt.c1 < t.c1
)
SELECT
    SUM(t.rst) OVER (ORDER BY t.ord ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS group_number,
    t.c1
FROM
    (
        SELECT
            t.c1,
            t.rst,
            t.ord
        FROM
            (
                SELECT
                    rt.c1,
                    CASE
                        WHEN rt.c1_min = MIN(rt.c1_min) OVER (ORDER BY rt.c1_min, rt.c1 ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) THEN 0
                        ELSE 1
                    END AS rst,
                    ROW_NUMBER() OVER (ORDER BY rt.c1_min, rt.c1) AS ord,
                    ROW_NUMBER() OVER (PARTITION BY rt.c1 ORDER BY rt.c1_min, rt.cnt) AS qfy
                FROM
                    rt
            ) AS t
        WHERE
            t.qfy = 1
    ) AS t;

【讨论】:

    猜你喜欢
    • 2014-01-12
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 2010-10-03
    • 1970-01-01
    • 2022-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多