SQL查询计算天数和出现次数

TSQL Query Calculating number of days and number of occurrences

我在编写从查询中总结一些库存信息的查询时遇到了一些问题。

我一直在尝试一些 CTE(通用 table 表达式)分组和子查询以及 LAG 函数来尝试汇总数据。奇怪的是,最近几天我陷入了这个问题。

这是我正在处理的数据示例。

--Optional create table
--Drop table testdata
--Create table testdata ( Part int, StockDate date, OutOfStock bit);

with inventorydata(Part, StockDate, OutOfStock) as
(
  select 1000, '1/1/2019',1
  union 
  select 1000,'1/2/2019',1
  union 
  select 1000, '1/3/2019',1
  union
  select 1000, '1/4/2019',0
  union
  select 1000, '1/5/2019',1
  union 
  select 1005, '1/1/2019',0
  union 
  select 1005,'1/2/2019',1
  union 
  select 1005, '1/3/2019',1
  union
  select 1005, '1/4/2019',1
  union
  select 1005, '1/5/2019',0
)

--Insert into testdata ( Part,StockDate,OutOfStock)
Select Part,StockDate,OutOfStock from inventorydata
--Select * from testdata 

输出

Part        StockDate OutOfStock
----------- --------- -----------
1000        1/1/2019  1
1000        1/2/2019  1
1000        1/3/2019  1
1000        1/4/2019  0
1000        1/5/2019  1
1005        1/1/2019  0
1005        1/2/2019  1
1005        1/3/2019  1
1005        1/4/2019  1
1005        1/5/2019  0

我正在尝试获得所需的输出。

Part        StockDate BackInStock Occurance
----------- --------- ----------- -----------
1000        1/1/2019  1/3/2019    1
1000        1/5/2019  1/5/2019    1
1005        1/2/2019  1/4/2019    1

非常感谢任何帮助。 谢谢。

如果不提供更多详细信息,则很难确定您的确切目标。您想要的输出缺少一些有助于提供更好答案的细节。话虽如此,希望这对您有所帮助。

我的假设:

  • 您要查找零件缺货的时间段,并记下零件首次缺货的日期和重新入库的日期
  • 我将 "back in stock" 日期解释为某件商品第一次有记录表明它没有缺货的日期。例如,根据数据,第 1000 部分在 2019 年 1 月 1 日缺货,从 2019 年 1 月 4 日开始有货,而不是示例中的 2019 年 1 月 3 日
  • 如果该商品没有库存,那么我们不需要 "back in stock" 日期

我将把你的示例数据放入一个临时文件中 table 让演示更容易一些:

with inventorydata(Part, StockDate, OutOfStock) as
(
  select 1000, '1/1/2019',1
  union 
  select 1000,'1/2/2019',1
  union 
  select 1000, '1/3/2019',1
  union
  select 1000, '1/4/2019',0
  union
  select 1000, '1/5/2019',1
  union 
  select 1005, '1/1/2019',0
  union 
  select 1005,'1/2/2019',1
  union 
  select 1005, '1/3/2019',1
  union
  select 1005, '1/4/2019',1
  union
  select 1005, '1/5/2019',0
)

Select Part,StockDate,OutOfStock 
INTO #Test
from inventorydata

考虑以下几点:

SELECT 
    Part,
    StockDate,
    BackInStockDate
FROM
(
    SELECT 
        Part,
        StockDate,
        OutOfStock,
        LEAD(StockDate, 1) OVER (PARTITION BY Part ORDER BY StockDate) AS BackInStockDate
    FROM
    (
        SELECT 
            Part,
            StockDate,
            OutOfStock,
            LAG(OutOfStock, 1) OVER (PARTITION BY Part ORDER BY StockDate) AS PrevOutOfStock
        FROM #Test
    ) AS InnerData
    WHERE 
        OutOfStock <> PrevOutOfStock
        OR PrevOutOfStock IS NULL
) AS OuterData
WHERE
    OutOfStock = 1

InnerData 查询提取每条记录以及前一行的 OutOfStock 值。我们使用它来仅查找那些表示库存状态从有货变为缺货或反之亦然的日期的行。这是由OutOfStock <> PrevOutOfStockPrevOutOfStock IS NULL决定的。

一旦我们有了表示变化的行,我们就会查看 下一个 行,以获取我们看到零件状态从当前行中表示的状态发生变化的日期.'

最后,我们过滤掉 OutOfStock = 0 的行,因为这些行代表我们忽略的有货期。这给了我们以下结果:

Part    StockDate   BackInStockDate
------- ----------- ----------------
1000    1/1/2019    1/4/2019
1000    1/5/2019    NULL
1005    1/2/2019    1/5/2019

如果这不是您想要的值,您可以修改结构以获得不同的 BackInStockDate,并添加一些计数以获得任何 Occurances 应该是的值。