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 <> PrevOutOfStock
和PrevOutOfStock 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
应该是的值。
我在编写从查询中总结一些库存信息的查询时遇到了一些问题。
我一直在尝试一些 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 <> PrevOutOfStock
和PrevOutOfStock 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
应该是的值。