从一周的第一天和最后一天的字段中获取值

时间:2017-05-16 13:38:09

标签: sql-server dayofweek

我需要从一周的第一天和最后一天的字段中提取值。基本上我需要在开始和结束时显示单位的状态。 周是从星期一到星期日确定的,我需要提取的表格如下:

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个产品编号。你能帮我解决一下这个问题吗?

谢谢!

2 个答案:

答案 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;