Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.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 server 行号需要递归/循环查询帮助_Sql Server_Loops_Recursive Query_Row Number_Ssms 2017 - Fatal编程技术网

Sql server 行号需要递归/循环查询帮助

Sql server 行号需要递归/循环查询帮助,sql-server,loops,recursive-query,row-number,ssms-2017,Sql Server,Loops,Recursive Query,Row Number,Ssms 2017,我希望能够追溯材料、用于移动的设备和计时的移动表,从字段中的指定值开始,并根据共享值在不同行的另一个字段中查找该值 在下表中,我需要能够追溯到,例如,从端码“M”所有相关行,一直追溯到StartCode A。然后,我可能希望能够追溯到从端码“U”到StartCode“N”的所有行 在表中,起始代码(物料)A和B被移动为末端代码C。末端代码C随后成为起始代码,然后与起始代码E一起移动为末端代码F等。橙色/蓝色行表示物料移动组 由此,我想创建一个新的表/视图,它在下一个事件发生时将StartedAt

我希望能够追溯材料、用于移动的设备和计时的移动表,从字段中的指定值开始,并根据共享值在不同行的另一个字段中查找该值

在下表中,我需要能够追溯到,例如,从端码“M”所有相关行,一直追溯到StartCode A。然后,我可能希望能够追溯到从端码“U”到StartCode“N”的所有行

在表中,起始代码(物料)A和B被移动为末端代码C。末端代码C随后成为起始代码,然后与起始代码E一起移动为末端代码F等。橙色/蓝色行表示物料移动组

由此,我想创建一个新的表/视图,它在下一个事件发生时将StartedAt作为一个名为“EndedAt”的新字段引入。它将如下所示:

我创建了一个递归查询,它使用ROW_NUMBER和CTE将StartedAt作为一个新字段“EndedAt”传入

然后,我尝试使用一个嵌套的SELECT语句来查找与EndCode“M”相关的所有StartCodes,试图在表中循环搜索StartCode列中的所有相关EndCodes。这只带来了几行。我将嵌套语句重复几次,使其穿过不同的行

我需要帮助来获取创建所需表/视图所需的所有相关开始/结束代码

最终,一份报告将附在表格上,允许表格通过所选的端码参数(如M、U等)进行过滤


EndedAt
是一个简单的连接:

SELECT
    S.StartCode,
    S.StartedAt,
    S.EndCode,
    E.StartedAt AS EndedAt
FROM
    MyTable AS S
    LEFT JOIN MyTable AS E ON S.EndCode = E.StartCode
结果:

StartCode   StartedAt                   EndCode     EndedAt
A           2019-01-01 01:00:00.000     C           2019-01-01 03:00:00.000
B           2019-01-01 02:15:00.000     C           2019-01-01 03:00:00.000
C           2019-01-01 03:00:00.000     F           2019-01-01 04:14:00.000
D           2019-01-01 03:19:00.000     F           2019-01-01 04:14:00.000
E           2019-01-01 04:00:00.000     F           2019-01-01 04:14:00.000
F           2019-01-01 04:14:00.000     G           2019-01-01 05:00:00.000
G           2019-01-01 05:00:00.000     J           2019-01-01 06:00:00.000
H           2019-01-01 05:37:00.000     J           2019-01-01 06:00:00.000
I           2019-01-01 05:45:00.000     J           2019-01-01 06:00:00.000
J           2019-01-01 06:00:00.000     L           2019-01-01 07:00:00.000
K           2019-01-01 06:09:00.000     L           2019-01-01 07:00:00.000
L           2019-01-01 07:00:00.000     M           NULL
N           2019-01-01 09:20:00.000     P           2019-01-01 09:45:00.000
O           2019-01-01 09:37:00.000     P           2019-01-01 09:45:00.000
P           2019-01-01 09:45:00.000     Q           2019-01-01 11:00:00.000
Q           2019-01-01 11:00:00.000     T           2019-01-01 11:58:00.000
R           2019-01-01 11:10:00.000     T           2019-01-01 11:58:00.000
S           2019-01-01 11:47:00.000     T           2019-01-01 11:58:00.000
T           2019-01-01 11:58:00.000     U           NULL
CurrentCode CurrentStartAt              LastCode    EndedAt                     PreviousCode    RecursionLevel  RecursionPath
A           2019-01-01 01:00:00.000     J           2019-01-01 06:00:00.000     C               4               J->G->F->C->A
B           2019-01-01 02:15:00.000     J           2019-01-01 06:00:00.000     C               4               J->G->F->C->B
C           2019-01-01 03:00:00.000     J           2019-01-01 06:00:00.000     F               3               J->G->F->C
D           2019-01-01 03:19:00.000     J           2019-01-01 06:00:00.000     F               3               J->G->F->D
E           2019-01-01 04:00:00.000     J           2019-01-01 06:00:00.000     F               3               J->G->F->E
F           2019-01-01 04:14:00.000     J           2019-01-01 06:00:00.000     G               2               J->G->F
G           2019-01-01 05:00:00.000     J           2019-01-01 06:00:00.000     J               1               J->G
H           2019-01-01 05:37:00.000     J           2019-01-01 06:00:00.000     J               1               J->H
I           2019-01-01 05:45:00.000     J           2019-01-01 06:00:00.000     J               1               J->I
您可以使用以下方法显示层次结构(在本例中,使用自底向上的递归CTE方法)。首先确保数据中没有循环

编辑:如果您想检查层次结构中的任何步骤以及向上的步骤,锚定需要是任何代码(不仅仅是最后一个
M
U
),因此我删除了锚定中的
WHERE

DECLARE @EndCodeFilter CHAR(1) = 'J'

;WITH RecursiveCodes AS
(
    -- Anchor
    SELECT
        LastCode = M.EndCode,
        CurrentCode = M.StartCode,
        PreviousCode = M.EndCode,
        RecursionLevel = 1,
        RecursionPath = CONVERT(NVARCHAR(MAX), M.EndCode + '->' + M.StartCode),
        CurrentStartAt = M.StartedAt
    FROM
        MyTable AS M

    UNION ALL

    -- Recursion: link related codes
    SELECT
        LastCode = R.LastCode,
        CurrentCode = M.StartCode,
        PreviousCode = M.EndCode,
        RecursionLevel = R.RecursionLevel + 1,
        RecursionPath = R.RecursionPath + '->' + M.StartCode,
        CurrentStartAt = M.StartedAt
    FROM
        RecursiveCodes AS R
        INNER JOIN MyTable AS M ON R.CurrentCode = M.EndCode
)
SELECT
    R.CurrentCode,
    R.CurrentStartAt,
    R.LastCode,
    EndedAt = E.StartedAt,
    R.PreviousCode,
    R.RecursionLevel,
    R.RecursionPath
FROM
    RecursiveCodes AS R
    LEFT JOIN MyTable AS E ON R.LastCode = E.StartCode
WHERE
    R.LastCode = @EndCodeFilter
ORDER BY
    R.CurrentCode,
    R.LastCode
OPTION
    (MAXRECURSION 0)
结果:

StartCode   StartedAt                   EndCode     EndedAt
A           2019-01-01 01:00:00.000     C           2019-01-01 03:00:00.000
B           2019-01-01 02:15:00.000     C           2019-01-01 03:00:00.000
C           2019-01-01 03:00:00.000     F           2019-01-01 04:14:00.000
D           2019-01-01 03:19:00.000     F           2019-01-01 04:14:00.000
E           2019-01-01 04:00:00.000     F           2019-01-01 04:14:00.000
F           2019-01-01 04:14:00.000     G           2019-01-01 05:00:00.000
G           2019-01-01 05:00:00.000     J           2019-01-01 06:00:00.000
H           2019-01-01 05:37:00.000     J           2019-01-01 06:00:00.000
I           2019-01-01 05:45:00.000     J           2019-01-01 06:00:00.000
J           2019-01-01 06:00:00.000     L           2019-01-01 07:00:00.000
K           2019-01-01 06:09:00.000     L           2019-01-01 07:00:00.000
L           2019-01-01 07:00:00.000     M           NULL
N           2019-01-01 09:20:00.000     P           2019-01-01 09:45:00.000
O           2019-01-01 09:37:00.000     P           2019-01-01 09:45:00.000
P           2019-01-01 09:45:00.000     Q           2019-01-01 11:00:00.000
Q           2019-01-01 11:00:00.000     T           2019-01-01 11:58:00.000
R           2019-01-01 11:10:00.000     T           2019-01-01 11:58:00.000
S           2019-01-01 11:47:00.000     T           2019-01-01 11:58:00.000
T           2019-01-01 11:58:00.000     U           NULL
CurrentCode CurrentStartAt              LastCode    EndedAt                     PreviousCode    RecursionLevel  RecursionPath
A           2019-01-01 01:00:00.000     J           2019-01-01 06:00:00.000     C               4               J->G->F->C->A
B           2019-01-01 02:15:00.000     J           2019-01-01 06:00:00.000     C               4               J->G->F->C->B
C           2019-01-01 03:00:00.000     J           2019-01-01 06:00:00.000     F               3               J->G->F->C
D           2019-01-01 03:19:00.000     J           2019-01-01 06:00:00.000     F               3               J->G->F->D
E           2019-01-01 04:00:00.000     J           2019-01-01 06:00:00.000     F               3               J->G->F->E
F           2019-01-01 04:14:00.000     J           2019-01-01 06:00:00.000     G               2               J->G->F
G           2019-01-01 05:00:00.000     J           2019-01-01 06:00:00.000     J               1               J->G
H           2019-01-01 05:37:00.000     J           2019-01-01 06:00:00.000     J               1               J->H
I           2019-01-01 05:45:00.000     J           2019-01-01 06:00:00.000     J               1               J->I

最好以
格式化文本
的形式提供示例数据,或者更好地以sql FIDLE的形式提供示例数据。EndedAt列是一个简单而直接的连接(不需要递归或CTE)。对于M到A,如果您能发布完整的DML和DDL示例,我可以帮助您。同时删除bucket列,因为它们对您的问题不重要。请从层次关系中指定您想要的确切输出。好的,使用SL FIDLE,请参阅编辑。谢谢:)我试试看。谢谢,埃兹洛。我能看到的唯一问题是,如果根据我在初始帖子中的示例,我只想,例如,追溯链接到EndCode M和EndCode的所有开始/结束代码,并显示第一组结果中列出的信息。唯一的方法是按照Stat/endcode从字母M返回到A,这是我不能用你(非常感谢)的帮助做到的?层次结构代码可以工作,必须将转换部分更改为NVARCHAR而不是VARCHAR,它工作了。我只需要能够像第一次输出中那样显示一个表,我可以说“只显示与EndCode M相关的行”。我想使用一个@parameter,使用EndCode字段作为值进行选择。@Jimbo我已经编辑了按参数查询的答案。谢谢所有帮助,@EnZo。问题是每一行的EndedAt应该是下一行的StartedAt值,目前它只为每一行提供最后一个StartedAt日期。另外,如果您将参数字母J更改为字母M或U,则EndedAt值都为空。@Jimbo我相信您现在可以编辑查询以满足您的需要。而且M和U没有时间戳,所以你永远也不会知道他们的结束日期。