Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 查找列值链_Sql_Sql Server_Tsql_Sql Server 2008 R2_Common Table Expression - Fatal编程技术网

Sql 查找列值链

Sql 查找列值链,sql,sql-server,tsql,sql-server-2008-r2,common-table-expression,Sql,Sql Server,Tsql,Sql Server 2008 R2,Common Table Expression,表: 记录: create table tbl_test ( col1 int, col2 int ); 查询:我想以111->112->113->114->111的形式找到完整的col1和col2链 这是一条完整的链,因为它以111开头,以111结尾 预期产出2: INSERT INTO tbl_test VALUES(111,112), (112,113), (1

表:

记录:

create table tbl_test
(
    col1 int,
    col2 int
);
查询:我想以111->112->113->114->111的形式找到完整的col1和col2链 这是一条完整的链,因为它以111开头,以111结尾

预期产出2:

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

为了更容易理解,这里有更多的细节。首先,我们将使用递归。然后,我们需要知道每个组的起始值,以便知道何时停止递归。在您的例子中,这是col01的最小值,但我们可以有许多起始值,因此我添加了一个组id-您可以使用它来过滤最终结果

col1    col2
-------------
111     112
112     113
113     114
114     111 

如果我发现另一条链,例如117->118->119->117,需要做什么更改?@MAK当然可以。这就是为什么您有组ID。您只需在第一次选择中标识这些值。
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;