Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.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 如何从TSQL中的日志向后计数行?_Sql Server_Tsql - Fatal编程技术网

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:请在你的问题中发布你的表结构。所以我可以适当地帮助你。我现在已经在问题中添加了表结构。