【问题标题】:Find chain of columns values - Follow-Up查找列值链 - 跟进
【发布时间】:2018-12-16 20:11:00
【问题描述】:

这是this的后续问题。

表:

create table tbl_test
(
    col1 int,
    col2 int
);

记录:

已编辑

INSERT INTO tbl_test VALUES(111,112),
                            (112,113),
                            (113,114),
                            (114,111),
                            (115,116),
                            (117,118),
                            (118,119),
                            (119,117), --Added
                            (111,130),
                            (120,121),
                            (122,123),
                            (123,111),
                            (124,111);

查询:我想找到111->112->113->114->111形式的完整链col1和col2 (这是完整的链,因为它以111 开头并以111 结尾)。

注意:表中可能有多个链。

预期输出 2:

col1    col2
-------------
111     112
112     113
113     114
114     111 
117     118
118     119  
119     117

用gotqn的回答试过了:

WITH DataSource AS
(
    SELECT col1
          ,col2
          ,0 as level
          ,ROW_NUMBER() OVER(ORDER BY Col1, col2) AS [groupID]
          ,0 as anchorMatched
          ,col1 as startValue
    FROM tbl_test
    WHERE col1 IN (SELECT MIN(col1) FROM tbl_test)
    UNION ALL
    SELECT A.col1
          ,A.col2
          ,level + 1
          ,B.[groupID]
          ,anchorMatched + CASE WHEN A.col1 = B.col2 AND A.col2 = B.startValue THEN 1 ELSE 0 END
          ,b.startValue
    FROM tbl_test A
    INNER JOIN DataSource B
        ON A.col1 = B.col2
    WHERE (anchorMatched = 0 AND A.col1 <> B.startValue)
)
SELECT *
FROM DataSource
WHERE groupID = 1;

但无法获得第二条链。

【问题讨论】:

  • 记录似乎代表图的边缘,并且您的“完整”链似乎是圆圈。显然,边不限于类型 (x, x+1) 和最终“完成”链的类型,如边 (111, 130) 所示。是否有任何限制适用于记录和可能的“完整链”,例如“完整中除了一条边之外的所有边都包含增加的节点”?

标签: sql-server tsql sql-server-2008-r2 common-table-expression recursive-query


【解决方案1】:

试试这个

WITH DataSource AS
(
    SELECT col1
          ,col2
          ,0 as level
          ,ROW_NUMBER() OVER(ORDER BY Col1, col2) AS [groupID]
          ,0 as anchorMatched
          ,col1 as startValue
    FROM tbl_test
    WHERE col1 IN (Select col2 from tbl_test where (col2-col1)<>1 )
    UNION ALL
    SELECT A.col1
          ,A.col2
          ,level + 1
          ,B.[groupID]
          ,anchorMatched + CASE WHEN A.col2 = B.startValue THEN 1 ELSE 0 END
          ,b.startValue
    FROM tbl_test A
    INNER JOIN DataSource B
        ON A.col1 = B.col2
    WHERE (anchorMatched = 0 AND A.col1 <> B.startValue AND (A.col2 = A.col1 +1 or A.col2 = B.startValue))
)
SELECT *
FROM DataSource where groupID in (SELECT groupID FROM DataSource where anchorMatched = 1)
order by col1,groupID

【讨论】:

  • 如果第四行的 col2 值从 111 更改为 112(所以第一个“链”应该是 112 -> 113 -> 114 -> 112)怎么办?
  • @WolfgangK 好收获!它会进入无限循环。编辑了我的答案。
  • @WolfgangK 是的。什么都不应该发生
  • 好吧,如果你知道 111 -> 130 -> 123 -> 111 不是链条,那么你知道的比我多。 :-)
  • 好吧,我想我会的。不是 OP 定义的“链”。
猜你喜欢
  • 2018-12-16
  • 2020-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-22
  • 1970-01-01
  • 1970-01-01
  • 2012-01-24
相关资源
最近更新 更多