TSQL-如何确定给定星期数的一周的第一天和最后一天

时间:2019-02-14 18:10:29

标签: sql sql-server

我的数据格式如下:

TrDate:2018-01-01 00:00:00.000 | Amount: 10.00
TrDate:2018-01-02 00:00:00.000 | Amount: 20.00

我想每周一次合并数据:

Week:1 | Start Date: | End Date:| Total Amount

我有一个查询,它每周汇总一次数据,但是我不知道如何获取各个星期的开始和结束日期。这是我的查询:

 SELECT      DATEPART(wk, trdate)     weekno,
     round(SUM(amount),2) AS total_amount
 FROM        <table>
 GROUP BY    DATEPART(wk, trdate);

仅供参考:一周从星期日开始,到星期六结束。

3 个答案:

答案 0 :(得分:3)

尝试一下:

select weekno, weekStart, weekEnd,   round(SUM(amount),2) AS total_amount from 
(
  SELECT      
    DATEPART(wk, trdate)     weekno,
    DATEADD(dd, -(DATEPART(dw, trdate)-1), trdate) [WeekStart],
    DATEADD(dd, 7-(DATEPART(dw, trdate)), trdate) [WeekEnd],
    amount
  from table1
)t
group by Weekno, weekstart, weekend

答案 1 :(得分:1)

您可以使用此表达式查找给定日期的上一个星期日(无论@@DATEFIRST的设置如何,它都起作用):

SELECT DATEADD(DAY, -CASE DATENAME(WEEKDAY, <date>)
    WHEN 'SUNDAY'    THEN 0
    WHEN 'MONDAY'    THEN 1
    WHEN 'TUESDAY'   THEN 2
    WHEN 'WEDNESDAY' THEN 3
    WHEN 'THURSDAY'  THEN 4
    WHEN 'FRIDAY'    THEN 5
    WHEN 'SATURDAY'  THEN 6
END, <date>) AS weekstart

您可以按如下所示在查询中使用它:

SELECT weekno, total_amount, DATEADD(DAY, -CASE DATENAME(WEEKDAY, refdate)
        WHEN 'SUNDAY'    THEN 0
        WHEN 'MONDAY'    THEN 1
        WHEN 'TUESDAY'   THEN 2
        WHEN 'WEDNESDAY' THEN 3
        WHEN 'THURSDAY'  THEN 4
        WHEN 'FRIDAY'    THEN 5
        WHEN 'SATURDAY'  THEN 6
    END, refdate) AS weekstart, DATEADD(DAY, CASE DATENAME(WEEKDAY, refdate)
        WHEN 'SUNDAY'    THEN 6
        WHEN 'MONDAY'    THEN 5
        WHEN 'TUESDAY'   THEN 4
        WHEN 'WEDNESDAY' THEN 3
        WHEN 'THURSDAY'  THEN 2
        WHEN 'FRIDAY'    THEN 1
        WHEN 'SATURDAY'  THEN 0
    END, refdate) AS weekend
FROM (
    SELECT DATEPART(wk, trdate) weekno
         , ROUND(SUM(amount),2) AS total_amount
         , MIN(trdate) AS refdate
    FROM t
    GROUP BY DATEPART(wk, trdate)
) AS cte

答案 2 :(得分:0)

解决方案

 SELECT 
    weekno,
    convert(varchar(10),DATEADD(dd, 1 - DATEPART(dw, date1), date1),111) startdate,
    convert(varchar(10),DATEADD(dd, 7 - DATEPART(dw, date2), date2),111) enddate,
    total_amount
    from
    (
          SELECT  
            DATEPART(wk, trdate) weekno,
            cast(min(trdate) as date) as date1, 
            cast(max(trdate) as date) as date2, 
            round(SUM(amount),2) AS total_amount
         FROM        <table>
         GROUP BY    DATEPART(wk, trdate)
     ) t

产生这样的输出(注意:我添加了一些自己的数据来测试一些边缘情况)。

enter image description here

注释

  1. 尚不清楚问题中的datetime值是否可以具有除午夜以外的时间成分。我的答案假设可能是非午夜时间。
  2. 在年初和/或年底,weekno值可能看起来很奇怪,但是对于这些极端情况,OP的查询会为weekno产生相同的值。
  3. OP的查询或迄今为止的任何答案都没有按年限制数据,它们仅按周号进行分组。因此,如果包括来自多年的数据,您仍将仅获得53行,并且每一行将包含该周数据中所有年份的汇总数据。然后,开始日期和结束日期会重叠并且看起来很奇怪。您可以按年份添加其他分组以进一步划分,但是最简单的解决方法是将数据限制为一年,在GROUP BY子句之前使用WHERE子句,例如:

     WHERE trdate >= '2018/01/01' and trdate < '2019/01/01'