我希望能够从物料移动表,用于移动物料的设备和计时表中向后追溯,从一个字段中的指定值开始,然后根据以下内容在不同行中的另一个字段中找到该值共享的价值。
在下表中,我需要能够追溯,例如,从EndCode'M'一直追溯到StartCode A的所有相关行。然后,我可能希望能够追溯全部从EndCode'U'返回StartCode'N'的行。
在表中,将StartCode(物料)A和B移动为EndCodeC。然后将EndCode C变为StartCodeD,然后与StartCode E一同移动为EndCode F等。橙色/蓝色行表示物料移动的组。
由此,我想创建一个新表/视图,将下一个事件的StartedAt时间作为名为“ EndedAt”的新字段进行处理。看起来像这样:
我创建了一个递归查询,该查询使用ROW_NUMBER和CTE来将StartedAt作为“ EndedAt”的新字段引入。
然后,我尝试使用嵌套的SELECT语句查找与EndCode'M'相关的所有StartCode,以尝试遍历表以在StartCode列中搜索所有相关的EndCode。这只会带来一些行。我三遍重复嵌套的语句,使它遍历不同的行。
我需要帮助来挑选创建所需表/视图所需的所有相关开始/结束代码。
最终,报告将附在表格上,使表格可以通过选定的EndCode参数(例如M,U等)进行过滤
CREATE TABLE MyTable (
`StartCode` VARCHAR(1),
`StartedAt` DATETIME,
`EndCode` VARCHAR(1)
);
INSERT INTO MyTable (`StartCode`, `StartedAt`, `EndCode`)
VALUES
('A', '01/01/2019 01:00', 'C'),
('B', '01/01/2019 02:15', 'C'),
('C', '01/01/2019 03:00', 'F'),
('D', '01/01/2019 03:19', 'F'),
('E', '01/01/2019 04:00', 'F'),
('F', '01/01/2019 04:14', 'G'),
('G', '01/01/2019 05:00', 'J'),
('H', '01/01/2019 05:37', 'J'),
('I', '01/01/2019 05:45', 'J'),
('J', '01/01/2019 06:00', 'L'),
('K', '01/01/2019 06:09', 'L'),
('L', '01/01/2019 07:00', 'M'),
('N', '01/01/2019 09:20', 'P'),
('O', '01/01/2019 09:37', 'P'),
('P', '01/01/2019 09:45', 'Q'),
('Q', '01/01/2019 11:00', 'T'),
('R', '01/01/2019 11:10', 'T'),
('S', '01/01/2019 11:47', 'T'),
('T', '01/01/2019 11:58', 'U');
答案 0 :(得分:1)
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
您可以显示以下层次结构(在这种情况下,递归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)
结果:
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