我正在尝试编写一个查询,它将递归地寻找起始或部件号已更改。
有一个表stktrans
保存任何订单的IN和OUT交易。
当某些内容被发送OUT时,它将有一个IN_Nr,可用于追溯IN交易。 OrderNr 将IN链接到OUT
编辑:给定任何 IN_Nr,我希望能够追溯到购买它的原始订单。下表中 - TransID 1。但显示了事件的完整时间线,如下表所示。
回溯之间的节奏如下图:
目前,我有一个非常非动态的查询,可以从任何给定的 IN_Nr 追溯到 4 个级别:
DECLARE @IN_Nr INT = 232753
;WITH StkOUT_CTE AS (
SELECT
ST.TransID,
ST.Part,
ST.IN_Nr,
ST.OUT_Nr,
ST.OrderNr,
ST.Type
FROM
StkTrans ST
WHERE
OUT_Nr IS NOT NULL
AND ST.Type = 'OUT'
),
StkIN_CTE AS (
SELECT
ST.TransID,
ST.Part,
ST.IN_Nr,
ST.OUT_Nr,
ST.OrderNr,
ST.Type
FROM
StkTrans ST
INNER JOIN StkOUT_CTE SI ON SI.IN_Nr = ST.IN_Nr
WHERE
ST.Type = 'IN'
)
SELECT
*
FROM
(
SELECT
1 RowOrder, *
FROM
StkOUT_CTE
WHERE IN_Nr = @IN_Nr
UNION
SELECT
2 RowOrder, *
FROM
StkIN_CTE
WHERE IN_Nr = @IN_Nr
UNION
SELECT 3 RowOrder, *
FROM
StkOUT_CTE
WHERE
OrderNr = (SELECT OrderNr FROM StkIN_CTE WHERE IN_Nr = @IN_Nr)
UNION
SELECT 4 RowOrder, *
FROM
StkIN_CTE
WHERE
IN_Nr = (
SELECT IN_Nr
FROM
StkOUT_CTE
WHERE
OrderNr = (SELECT OrderNr FROM StkIN_CTE WHERE IN_Nr = @IN_Nr))
) ST
要创建类似的设置:
CREATE TABLE StkTrans (
TransID INT,
Part VARCHAR(25),
IN_Nr INT,
OUT_Nr INT,
OrderNr INT,
Type VARCHAR(3)
)
INSERT INTO StkTrans
(TransID, Part, IN_Nr, OUT_Nr, OrderNr, Type)
VALUES
(1, '123-1', 176573, NULL, 666000, 'IN' ),
(2, '123-1', 176573, 171516, 111222, 'OUT' ),
(3, '123-1', 179409, NULL, 111222, 'IN' ),
(4, '123-1', 179409, 198306, 123332, 'OUT' ),
(5, '123-1', 203944, NULL, 123332, 'IN' ),
(6, '123-1', 203944, 224789, 125707, 'OUT' ),
(7, '123-1', 232753, NULL, 125707, 'IN' ),
(8, '123-1', 232753, 232233, 888777, 'OUT' )
任何可能为我指明如何递归使用 CTE 的正确方向的指导都会很棒!
最佳答案
言外之意,也许这就是你想要的?
WITH rCTE AS(
SELECT *,
1 AS Iteration
FROM dbo.StkTrans ST
WHERE ST.IN_Nr = '232753'
AND ST.[Type] = 'IN'
UNION ALL
SELECT STi.*,
r.Iteration + 1
FROM dbo.StkTrans STo
JOIN dbo.StkTrans STi ON STo.IN_Nr = STi.IN_Nr
JOIN rCTE r ON STo.OrderNr = r.OrderNr
WHERE STo.[Type] = 'Out'
AND STi.[Type] = 'In')
SELECT TOP (1) TransID
FROM rCTE
ORDER BY ROW_NUMBER() OVER (ORDER BY Iteration DESC);
编辑: 也许这就是您所追求的。我现在也参数化了 rCTE 中的第一个数据集,以便于针对其他值进行测试。
DECLARE @IN_Nr int = 232753;
WITH rCTE AS(
SELECT V.*,
1 AS Iteration
FROM dbo.StkTrans STo
JOIN dbo.StkTrans STi ON STo.IN_Nr = STi.IN_Nr
CROSS APPLY (VALUES(STo.TransID,STo.Part,STo.IN_Nr,STo.OUT_Nr,STo.OrderNr,STo.[Type]),
(STi.TransID,STi.Part,STi.IN_Nr,STi.OUT_Nr,STi.OrderNr,STi.[Type]))V(TransID,Part,IN_Nr,OUT_Nr,OrderNr,[Type])
WHERE STo.IN_Nr = @IN_Nr
AND STo.[Type] = 'OUT'
AND STi.[Type] = 'In'
UNION ALL
SELECT V.*,
r.Iteration + 1
FROM dbo.StkTrans STo
JOIN dbo.StkTrans STi ON STo.IN_Nr = STi.IN_Nr
JOIN rCTE r ON STo.OrderNr = r.OrderNr
AND r.[Type] = 'In'
CROSS APPLY (VALUES(STo.TransID,STo.Part,STo.IN_Nr,STo.OUT_Nr,STo.OrderNr,STo.[Type]),
(STi.TransID,STi.Part,STi.IN_Nr,STi.OUT_Nr,STi.OrderNr,STi.[Type]))V(TransID,Part,IN_Nr,OUT_Nr,OrderNr,[Type])
WHERE STo.[Type] = 'Out'
AND STi.[Type] = 'In')
SELECT TransID,
Part,
IN_Nr,
OUT_Nr,
OrderNr,
[Type]
FROM rCTE
ORDER BY TransID DESC;
关于sql - 递归 CTE 查询循环直到满足条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68080790/