SQL递归CTE意外返回交替集

时间:2017-05-22 22:36:56

标签: sql sql-server recursion common-table-expression recursive-cte

我试图使用递归CTE一遍又一遍地重复相同的模式,当“Scenario”值增加时重置。 RowNumber重复1-21(根据需要),但每当“Scenario”为偶数时,“Vals”列中的项目太少,无法输入“Value”。我无法弄清楚代码的哪一部分导致我只有1个简短的场景。

以下是我在底部使用的代码的结果。

Scenario    RowNumber   Value   Vals
1   1   A   A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,B,C
1   2   A   A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,B,C
1   3   A   A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,B,C
1   4   A   A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,B,C
1   5   A   A,A,A,A,A,A,A,A,A,A,A,A,A,A,B,C
1   6   A   A,A,A,A,A,A,A,A,A,A,A,A,A,B,C
1   7   A   A,A,A,A,A,A,A,A,A,A,A,A,B,C
1   8   A   A,A,A,A,A,A,A,A,A,A,A,B,C
1   9   A   A,A,A,A,A,A,A,A,A,A,B,C
1   10  A   A,A,A,A,A,A,A,A,A,B,C
1   11  A   A,A,A,A,A,A,A,A,B,C
1   12  A   A,A,A,A,A,A,A,B,C
1   13  A   A,A,A,A,A,A,B,C
1   14  A   A,A,A,A,A,B,C
1   15  A   A,A,A,A,B,C
1   16  A   A,A,A,B,C
1   17  A   A,A,B,C
1   18  A   A,B,C
1   19  A   B,C
1   20  B   C
1   21  C   
2   1   A   A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,B,B,C
2   2   A   A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,B,B,C
2   3   A   A,A,A,A,A,A,A,A,A,A,A,A,A,A,B,B,C
2   4   A   A,A,A,A,A,A,A,A,A,A,A,A,A,B,B,C
2   5   A   A,A,A,A,A,A,A,A,A,A,A,A,B,B,C
2   6   A   A,A,A,A,A,A,A,A,A,A,A,B,B,C
2   7   A   A,A,A,A,A,A,A,A,A,A,B,B,C
2   8   A   A,A,A,A,A,A,A,A,A,B,B,C
2   9   A   A,A,A,A,A,A,A,A,B,B,C
2   10  A   A,A,A,A,A,A,A,B,B,C
2   11  A   A,A,A,A,A,A,B,B,C
2   12  A   A,A,A,A,A,B,B,C
2   13  A   A,A,A,A,B,B,C
2   14  A   A,A,A,B,B,C
2   15  A   A,A,B,B,C
2   16  A   A,B,B,C
2   17  A   B,B,C
2   18  B   B,C
2   19  B   C
2   20  C   
2   21  A   A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,B,B,C
3   1   A   A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,B,C,C
3   2   A   A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,B,C,C
3   3   A   A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,B,C,C
3   4   A   A,A,A,A,A,A,A,A,A,A,A,A,A,A,B,C,C
3   5   A   A,A,A,A,A,A,A,A,A,A,A,A,A,B,C,C
3   6   A   A,A,A,A,A,A,A,A,A,A,A,A,B,C,C
3   7   A   A,A,A,A,A,A,A,A,A,A,A,B,C,C
3   8   A   A,A,A,A,A,A,A,A,A,A,B,C,C
3   9   A   A,A,A,A,A,A,A,A,A,B,C,C
3   10  A   A,A,A,A,A,A,A,A,B,C,C
3   11  A   A,A,A,A,A,A,A,B,C,C
3   12  A   A,A,A,A,A,A,B,C,C
3   13  A   A,A,A,A,A,B,C,C
3   14  A   A,A,A,A,B,C,C
3   15  A   A,A,A,B,C,C
3   16  A   A,A,B,C,C
3   17  A   A,B,C,C
3   18  A   B,C,C
3   19  B   C,C
3   20  C   C
3   21  C   
4   1   A   A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,B,B,B,C
4   2   A   A,A,A,A,A,A,A,A,A,A,A,A,A,A,B,B,B,C
4   3   A   A,A,A,A,A,A,A,A,A,A,A,A,A,B,B,B,C
4   4   A   A,A,A,A,A,A,A,A,A,A,A,A,B,B,B,C
4   5   A   A,A,A,A,A,A,A,A,A,A,A,B,B,B,C
4   6   A   A,A,A,A,A,A,A,A,A,A,B,B,B,C
4   7   A   A,A,A,A,A,A,A,A,A,B,B,B,C
4   8   A   A,A,A,A,A,A,A,A,B,B,B,C
4   9   A   A,A,A,A,A,A,A,B,B,B,C
4   10  A   A,A,A,A,A,A,B,B,B,C
4   11  A   A,A,A,A,A,B,B,B,C
4   12  A   A,A,A,A,B,B,B,C
4   13  A   A,A,A,B,B,B,C
4   14  A   A,A,B,B,B,C
4   15  A   A,B,B,B,C
4   16  A   B,B,B,C
4   17  B   B,B,C
4   18  B   B,C
4   19  B   C
4   20  C   

这是我用来生成上述示例的代码。我哪里错了?

CREATE TABLE #temp3
        (
        Scenario INT
        ,Vals VARCHAR(64)
        ,LEN INT
        )
        ;
        WITH vals AS 
            (
            SELECT 
                v.*
            FROM 
                (VALUES ('A'), ('B'), ('C')) v(x)
            ),
        CTE AS 
                (
                SELECT CAST('A' AS VARCHAR(MAX)) AS STR, 0 AS LEN 
                UNION ALL
                SELECT (CTE.STR + ',' + vals.x), CTE.LEN + 1
                FROM 
                    CTE 
                JOIN vals
                    ON vals.x >= RIGHT(CTE.STR, 1)
                WHERE CTE.LEN < 19
                )
        INSERT INTO #temp3
        SELECT 
            ROW_NUMBER() OVER(ORDER BY STR + ',C') AS Scenario
            ,STR + ',C' AS Vals
            ,LEN
        FROM 
            CTE
        WHERE 
            STR + 'C' LIKE '%B%'
            AND LEN = 19
            ;

        -- Split strings created above into individual characters

        WITH cte(Scenario, Value, Vals) AS 
        (
            SELECT 
                Scenario 
                ,CAST(LEFT(Vals, CHARINDEX(',',Vals+',')-1) AS VARCHAR(10)) AS Value
                ,STUFF(Vals, 1, CHARINDEX(',',Vals+','), '') AS Vals
            FROM #temp3
            UNION ALL
            SELECT 
                Scenario
                ,CAST(LEFT(Vals, CHARINDEX(',',Vals+',')-1)  AS VARCHAR(10))
                ,STUFF(Vals, 1, CHARINDEX(',',Vals+','), '') 
            FROM cte
            WHERE Vals > ''
         )

       SELECT 
           Scenario
           ,ROW_NUMBER() OVER (PARTITION BY Scenario ORDER BY Scenario) RowNumber
           ,Value
           ,Vals
       FROM cte t

1 个答案:

答案 0 :(得分:0)

我不确定你所描述的问题是什么,但是ROW_NUMBER()应该使用ORDER BY子句来完全对每个分区中的行进行排序。

当您使用“按场景排序方案”时,未定义ROW_NUMBER()值的分配顺序。尝试像

这样的东西
WITH cte(Scenario,  depth, Value, Vals) AS 
        (
            SELECT 
                Scenario, 0 depth
                ,CAST(LEFT(Vals, CHARINDEX(',',Vals+',')-1) AS VARCHAR(10)) AS Value
                ,STUFF(Vals, 1, CHARINDEX(',',Vals+','), '') AS Vals
            FROM #temp3
            UNION ALL
            SELECT 
                Scenario,  depth+1
                ,CAST(LEFT(Vals, CHARINDEX(',',Vals+',')-1)  AS VARCHAR(10))
                ,STUFF(Vals, 1, CHARINDEX(',',Vals+','), '') 
            FROM cte
            WHERE Vals > ''
         )

       SELECT 
           Scenario 
           ,depth
           ,ROW_NUMBER() OVER (PARTITION BY Scenario ORDER BY depth ) RowNumber
           ,Value
           ,Vals
       FROM cte t