我需要从一周的第一天和最后一天的字段中提取值。基本上我需要在开始和结束时显示单位的状态。 周是从星期一到星期日确定的,我需要提取的表格如下:
Product number Quantity Date
1 15 4/3/2017 00:00:00.0000000
1 20 4/4/2017 00:00:00.0000000
1 20 4/5/2017 00:00:00.0000000
1 20 4/6/2017 00:00:00.0000000
1 25 4/7/2017 00:00:00.0000000
1 32 4/8/2017 00:00:00.0000000
1 37 4/9/2017 00:00:00.0000000
2 5 4/3/2017 00:00:00.0000000
2 10 4/4/2017 00:00:00.0000000
2 11 4/5/2017 00:00:00.0000000
2 12 4/6/2017 00:00:00.0000000
2 14 4/7/2017 00:00:00.0000000
2 15 4/8/2017 00:00:00.0000000
2 20 4/9/2017 00:00:00.0000000
在我的表中,我每个日期都有一个条目(日期字段实际上是日期时间),显示该特定日期的库存快照。请记住,4/3是星期一,4/9是星期日,我需要有4/3的数量和4/9的所有产品编号,所以结果应该是:
Week Product number Starting inventory Ending Inventory
From 4/3 to 4/9 1 15 37
From 4/3 to 4/9 2 5 20
我需要为所有四月份执行此操作,并且可能会在2017年通过sql server中的查询获得超过100个产品编号。你能帮我解决一下这个问题吗?
谢谢!
答案 0 :(得分:0)
DECLARE @Product TABLE( Product INT, Quanity INT, Date DATETIME2)
SET DATEFORMAT MDY
INSERT INTO @Product
( Product , Quanity , Date )
VALUES
(1,15,'4/3/2017 00:00:00.0000000')
,(1, 20,'4/4/2017 00:00:00.0000000')
,(1, 20,'4/5/2017 00:00:00.0000000')
,(1, 20,'4/6/2017 00:00:00.0000000')
,(1, 25,'4/7/2017 00:00:00.0000000')
,(1, 32,'4/8/2017 00:00:00.0000000')
,(1, 37,'4/9/2017 00:00:00.0000000')
,(2, 5, '4/3/2017 00:00:00.0000000')
,(2, 10,'4/4/2017 00:00:00.0000000')
,(2, 11,'4/5/2017 00:00:00.0000000')
,(2, 12,'4/6/2017 00:00:00.0000000')
,(2, 14,'4/7/2017 00:00:00.0000000')
,(2, 15,'4/8/2017 00:00:00.0000000')
,(2, 20,'4/9/2017 00:00:00.0000000')
SET DATEFIRST 1 --to specify that monday is the first day of the week
;WITH cteX
AS(
SELECT
DATEADD(WEEK, DATEDIFF(DAY, 0, [date])/7, 0) AS StartWeek
,DATEADD(WEEK, DATEDIFF(DAY, 0, [date])/7, 6) AS EndWeek
,*
FROM @Product
)
SELECT
'From ' + LEFT(CONVERT(VARCHAR(20), X.StartWeek,101 ), 5)
+ ' to ' + LEFT(CONVERT(VARCHAR(20), X.EndWeek,101 ), 5) 'Week'
, X.Product 'Product Number'
, MAX( CASE WHEN CAST(X.StartWeek AS DATE) = CAST([X].[Date] AS DATE)
THEN X.Quanity END )'Starting Inventory'
,MAX( CASE WHEN CAST(X.EndWeek AS DATE) = CAST([X].[Date] AS DATE)
THEN X.Quanity END )'Ending Inventory'
FROM
cteX X
GROUP BY
X.Product,X.StartWeek, X.EndWeek
产生以下输出:
Week Product Number Starting Inventory Ending Inventory
From 04/03 to 04/09 1 15 37
From 04/03 to 04/09 2 5 20
编辑以回答评论中的后续问题。
SELECT
'From ' + LEFT(CONVERT(VARCHAR(20), X.StartWeek,101 ), 5)
+ ' to ' + LEFT(CONVERT(VARCHAR(20), X.EndWeek,101 ), 5) 'Week'
, X.Product 'Product Number'
, MAX( CASE WHEN CAST(X.StartWeek AS DATE) = CAST([X].[Date] AS DATE)
THEN X.Quanity - T.Quantity END )'Starting Inventory'
,MAX( CASE WHEN CAST(X.EndWeek AS DATE) = CAST([X].[Date] AS DATE)
THEN X.Quanity - T.Quantity END )'Ending Inventory'
FROM
cteX X
INNER JOIN
dbo.OtherTable T ON T.Product = X.Product AND T.[date] BETWEEN X.StartWeek AND X.EndWeek
GROUP BY
X.Product,X.StartWeek, X.EndWeek
答案 1 :(得分:0)
理想情况下,您的数据库中有一个日历作为固定表, 但你可以像我在我的例子中那样生成它。 下面的查询不是最终结果,但确实提取了所有数据 在星期日/星期一你有'20170401','20170601'(6月1日除外)
declare @t table (prod int, q int, dt date);
insert into @t values
(1, 15 ,'4/3/2017 00:00:00.0000000'),
(1, 20 ,'4/4/2017 00:00:00.0000000'),
(1, 20 ,'4/5/2017 00:00:00.0000000'),
(1, 20 ,'4/6/2017 00:00:00.0000000'),
(1, 25 ,'4/7/2017 00:00:00.0000000'),
(1, 32 ,'4/8/2017 00:00:00.0000000'),
(1, 37 ,'4/9/2017 00:00:00.0000000'),
(2, 5 ,'4/3/2017 00:00:00.0000000'),
(2, 10 ,'4/4/2017 00:00:00.0000000'),
(2, 11 ,'4/5/2017 00:00:00.0000000'),
(2, 12 ,'4/6/2017 00:00:00.0000000'),
(2, 14 ,'4/7/2017 00:00:00.0000000'),
(2, 15 ,'4/8/2017 00:00:00.0000000'),
(2, 20 ,'4/9/2017 00:00:00.0000000');
with nums as
(
select number as n
from master..spt_values
where type = 'p'
and number < datediff(day, '20170401', '20170601')
),
calendar as
(
select dateadd(day, n, '20170401') as dt,
datename(dw,dateadd(day, n, '20170401')) as dw
from nums
where datename(dw,dateadd(day, n, '20170401')) in('sunday', 'monday')
)
select t.*,
c.dw
from @t t
join calendar c
on t.dt = c.dt;