【问题标题】:Take values from field for first and last day of week从字段中获取一周的第一天和最后一天的值
【发布时间】:2017-10-15 15:11:04
【问题描述】:

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

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 年 4 月和 2017 年 5 月通过 sql server 中的查询为 100 多个产品编号执行此操作。你能帮我看看怎么做吗?

谢谢!

【问题讨论】:

  • 如果星期天没有数据,你想要什么结果?周六数据还是空?
  • 如果星期天没有数据,应该只是空
  • 收盘股票肯定是周一 00:00 的股票,而不是周日 00:00 的股票?例如4/10/17 00:00,因为 4/09/17 00:00 的值是星期日开始时的值,而不是星期日结束时的值?
  • 嗨 JeffUK,按照这个例子,库存应该从 4/3 00:00:00 到 4/9 11:59:59 显示。谢谢

标签: sql-server dayofweek


【解决方案1】:
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

编辑以回答 cmets 中的后续问题。

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

【讨论】:

  • 非常感谢各位的帮助!!!真的很有帮助!如果我需要在查询中添加计算,例如将另一个表中的产品数量减去我在这里得到的数量,并记住该表几乎相同,并且我将按产品编号加入,我该怎么做?我不确定如何确定和加入两张表之间的周数。再次感谢
【解决方案2】:

理想情况下,您的数据库中有一个作为固定表的日历, 但是您可以像我在示例中那样生成它。 下面的查询不是最终结果,但它确实提取了所有数据 在“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;

【讨论】:

    猜你喜欢
    • 2021-07-21
    • 2016-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-22
    相关资源
    最近更新 更多