Sql server 如何从TSQL中的日志向后计数行?
我想计算一个位置上的托盘数量,在这个位置上你看不到有多少托盘。找出的唯一方法是假设您可以从记录的日志中倒数哪些托盘已移动到该位置 位置数量Sql server 如何从TSQL中的日志向后计数行?,sql-server,tsql,Sql Server,Tsql,我想计算一个位置上的托盘数量,在这个位置上你看不到有多少托盘。找出的唯一方法是假设您可以从记录的日志中倒数哪些托盘已移动到该位置 位置数量 LOCATION QUANTITY Loc_1 20 LOCATION QUANTITY Loc_1 20 Loc_2 10 SELECT BS.LOCATION, TL.PALL_NUM, BS.QUANTITY FROM BATCH_STOCK BS LEFT OUTER JOIN TRANS_LO
LOCATION QUANTITY
Loc_1 20
LOCATION QUANTITY
Loc_1 20
Loc_2 10
SELECT BS.LOCATION, TL.PALL_NUM, BS.QUANTITY
FROM BATCH_STOCK BS
LEFT OUTER JOIN TRANS_LOG TL
ON TL.ITEM_NUM = BS.ITEM_NUM AND LOC_TO = BS.LOCATION
ORDER BY BS.LOCATION
;WITH myCTE
AS
(
SELECT Location, Quantity AS Qty FROM #tLocationQty
UNION ALL
SELECT MoveToLocation, (Qty - t.Quantity) AS Qty FROM #tLog t
INNER JOIN myCTE
ON myCTE.Location = t.MoveToLocation
WHERE myCTE.Qty > 0
),
DistLocation
AS
(
SELECT DISTINCT Location FROM myCTE WHERE qty > 0
),
RowCnt
AS
(
SELECT Location, COUNT(DISTINCT Qty) AS Cnt FROM myCTE WHERE qty > 0
GROUP BY Location
)
--SELECT * FROM RowCnt
SELECT * FROM DistLocation
CROSS APPLY
(
SELECT TOP (SELECT top 1 Cnt FROM RowCnt r WHERE r.location = location)
PALL_NUM
FROM #tLog t
WHERE t.MoveToLocation = location
) c
日志
MOVED_TO_LOCATION QUANTITY PALLET_NUMBER
Loc_1 5 13
Loc_1 5 12
Loc_1 5 11
Loc_1 5 10 <-- Count the lines from here and up (count = 4).
Loc_1 5 9
...
我假设您可以以某种方式从最新到最早的时间戳递增计算日志中的数量,直到日志中的数量大于或等于位置上的当前数量。但我不知道该怎么做
伪代码
Quantity on location = 20
Row 1 in log: 5.
20 - 5 = 15 remaining.
Row 2 in log: 5.
15 - 5 = 10 remaining.
Row 3 in log: 5.
10 - 5 = 5 remaining.
Row 4 in log: 5.
5 - 5 = 0 remaining.
Then stop and return the rows.
编辑1:预期结果和我拥有的 位置数量
LOCATION QUANTITY
Loc_1 20
LOCATION QUANTITY
Loc_1 20
Loc_2 10
SELECT BS.LOCATION, TL.PALL_NUM, BS.QUANTITY
FROM BATCH_STOCK BS
LEFT OUTER JOIN TRANS_LOG TL
ON TL.ITEM_NUM = BS.ITEM_NUM AND LOC_TO = BS.LOCATION
ORDER BY BS.LOCATION
;WITH myCTE
AS
(
SELECT Location, Quantity AS Qty FROM #tLocationQty
UNION ALL
SELECT MoveToLocation, (Qty - t.Quantity) AS Qty FROM #tLog t
INNER JOIN myCTE
ON myCTE.Location = t.MoveToLocation
WHERE myCTE.Qty > 0
),
DistLocation
AS
(
SELECT DISTINCT Location FROM myCTE WHERE qty > 0
),
RowCnt
AS
(
SELECT Location, COUNT(DISTINCT Qty) AS Cnt FROM myCTE WHERE qty > 0
GROUP BY Location
)
--SELECT * FROM RowCnt
SELECT * FROM DistLocation
CROSS APPLY
(
SELECT TOP (SELECT top 1 Cnt FROM RowCnt r WHERE r.location = location)
PALL_NUM
FROM #tLog t
WHERE t.MoveToLocation = location
) c
结果
LOCATION PALL_NUM QUANTITY
Loc_2 16 5
Loc_2 15 5
Loc_2 14 5
Loc_1 13 5
Loc_1 12 5
Loc_1 11 5
Loc_1 10 5
... ...
Loc_1 1 5
LOCATION PALL_NUM
Loc_2 16
Loc_2 15
Loc_1 13
Loc_1 12
Loc_1 11
Loc_1 10
Location PALL_NUM
Loc_1 13
Loc_1 12
Loc_1 11
Loc_1 10
Loc_2 15
Loc_2 16
这只是第一个问题的扩展版本。但是显示了如果我不在日志中倒数,我将得到的输出。例如,Loc_2只有2个货盘,数量仍然在上面,但返回3个货盘,因为3个货盘已移动到该位置。Loc_1将返回13个货盘,但前9个货盘已被“挑选”,因此不再存在
预期结果
LOCATION PALL_NUM QUANTITY
Loc_2 16 5
Loc_2 15 5
Loc_2 14 5
Loc_1 13 5
Loc_1 12 5
Loc_1 11 5
Loc_1 10 5
... ...
Loc_1 1 5
LOCATION PALL_NUM
Loc_2 16
Loc_2 15
Loc_1 13
Loc_1 12
Loc_1 11
Loc_1 10
Location PALL_NUM
Loc_1 13
Loc_1 12
Loc_1 11
Loc_1 10
Loc_2 15
Loc_2 16
编辑2:表结构 批量库存
LOCATION = PK NVARCHAR(13) NOT NULL
QTY = NUMERIC (9,2) NOT NULL
传输日志
PALL_NUM = BIGINT NOT NULL
LOC_TO = NVARCHAR(16) NULL
QTY = NUMERIC(9,2) NULL
你在找一个连续的总数?这将返回4行:
select * from (
select *,
sum(QUANTITY) over (order by PALLET_NUMBER desc) as Quant
from yourtable
) X where Quant <= 20
结果:
LOCATION PALL_NUM QUANTITY Quant LOCATION QUANTITY
1 Loc_1 13 5 5 Loc_1 20
2 Loc_1 12 5 10 Loc_1 20
3 Loc_1 11 5 15 Loc_1 20
4 Loc_1 10 5 20 Loc_1 20
5 Loc_2 16 5 5 Loc_2 10
6 Loc_2 15 5 10 Loc_2 10
LOCATION PALL_NUM QUANTITY Quant NextQuant LOCATION QUANTITY
1 Loc_1 13 5 5 0 Loc_1 20
2 Loc_1 12 5 10 5 Loc_1 20
3 Loc_1 11 5 15 10 Loc_1 20
4 Loc_1 10 5 20 15 Loc_1 20
5 Loc_2 16 5 5 0 Loc_2 10
6 Loc_2 15 5 10 5 Loc_2 10
我做的好吧,这是我到目前为止所做的尝试。我已经使用递归CTE实现了预期的输出 模式
CREATE TABLE #tLocationQty
(
Location VARCHAR(10),
Quantity int
)
INSERT INTO #tLocationQty VALUES('Loc_1',20)
INSERT INTO #tLocationQty VALUES('Loc_2',10)
第二表模式
CREATE TABLE #tLog
(
MoveToLocation VARCHAR(10),
Quantity int,
PALL_NUM int
)
INSERT INTO #tLog VALUES('Loc_1',5, 13)
INSERT INTO #tLog VALUES('Loc_1',5, 12)
INSERT INTO #tLog VALUES('Loc_1',5, 11)
INSERT INTO #tLog VALUES('Loc_1',5, 10)
INSERT INTO #tLog VALUES('Loc_1',5, 9)
INSERT INTO #tLog VALUES('Loc_2',5, 16)
INSERT INTO #tLog VALUES('Loc_2',5, 15)
下面是查询
注意:-我没有使用orderby
子句。你必须按照你的要求使用它
查询
LOCATION QUANTITY
Loc_1 20
LOCATION QUANTITY
Loc_1 20
Loc_2 10
SELECT BS.LOCATION, TL.PALL_NUM, BS.QUANTITY
FROM BATCH_STOCK BS
LEFT OUTER JOIN TRANS_LOG TL
ON TL.ITEM_NUM = BS.ITEM_NUM AND LOC_TO = BS.LOCATION
ORDER BY BS.LOCATION
;WITH myCTE
AS
(
SELECT Location, Quantity AS Qty FROM #tLocationQty
UNION ALL
SELECT MoveToLocation, (Qty - t.Quantity) AS Qty FROM #tLog t
INNER JOIN myCTE
ON myCTE.Location = t.MoveToLocation
WHERE myCTE.Qty > 0
),
DistLocation
AS
(
SELECT DISTINCT Location FROM myCTE WHERE qty > 0
),
RowCnt
AS
(
SELECT Location, COUNT(DISTINCT Qty) AS Cnt FROM myCTE WHERE qty > 0
GROUP BY Location
)
--SELECT * FROM RowCnt
SELECT * FROM DistLocation
CROSS APPLY
(
SELECT TOP (SELECT top 1 Cnt FROM RowCnt r WHERE r.location = location)
PALL_NUM
FROM #tLog t
WHERE t.MoveToLocation = location
) c
输出
LOCATION PALL_NUM QUANTITY
Loc_2 16 5
Loc_2 15 5
Loc_2 14 5
Loc_1 13 5
Loc_1 12 5
Loc_1 11 5
Loc_1 10 5
... ...
Loc_1 1 5
LOCATION PALL_NUM
Loc_2 16
Loc_2 15
Loc_1 13
Loc_1 12
Loc_1 11
Loc_1 10
Location PALL_NUM
Loc_1 13
Loc_1 12
Loc_1 11
Loc_1 10
Loc_2 15
Loc_2 16
这在某种程度上适用于单个特定位置,但当我尝试在交叉应用中使用更一般意义上的(多个不同位置)时,它会崩溃。如果有更多位置,只需将
按位置划分
添加到总和/延迟中。问题是它在3个不同位置拾取4个不同的托盘。最终结果应为50个不同位置上的60个不同托盘。我编辑了这个问题来澄清这个问题,如果这可能有帮助的话。至少在我的测试中,这两个问题都很好。我再加上一个例子。这对我来说似乎很有效,结果看起来和我想要的相似。我只需要再检查一遍,几天后回来接受答案,如果答案确实正确。你能告诉我们你的预期输出吗?您需要Pall_Num
或只需计数(在本例中为4)我的预期put将是位置LOC_1的Pall_Num:13、12、11、10。然后,例如PALL_NUM:16,LOC_2为15,等等……在尝试应用这个之后,我得到了以下错误。类型在递归查询“myCTE”的“Location”列中的锚点和递归部分之间不匹配。@Danieboy:它在我的sql server实例中运行良好。我使用过SQL Server 2014。请再检查一遍。让我为您创建SQL FIDLE。我可以用表运行您的代码。但是当我试图将它应用到我自己的表时,我得到了错误。@Danieboy:请在你的问题中发布你的表结构。所以我可以适当地帮助你。我现在已经在问题中添加了表结构。