本周的SQL-周数不是年份&为什么查询在一个月内返回6周

时间:2012-10-06 14:53:35

标签: sql tsql

  

可能重复:
  TSQL Calculate week number of the month

这是我的SQL查询

 SELECT DATEPART(MONTH,PaymentDate) AS 'Month',
       DATEPART(WEEK,PaymentDate) AS 'Week #',
       SUM(COALESCE(Amount,0)) AS 'Amount',
       SUM(COALESCE(Balance,0)) AS 'Balance'
FROM Payment
WHERE     (MONTH(PaymentDate) = MONTH('2012-09-01'))
GROUP BY DATEPART(MONTH,PaymentDate),
DATEPART(WEEK,PaymentDate)
GO

enter image description here

我试图以每周方式获得一个月的总付款。

现在我有两个问题

1)正如你所看到的那样,它显示的是当年的第#周而不是那个月。

2)同时显示6周的小组而不是4小时。

我该如何解决这个问题。

感谢。

3 个答案:

答案 0 :(得分:4)

日期很难,因为日历不合逻辑。

我在这里的评论中假设格里高利历。

如果您按“每月的几周”进行分组,则需要先定义您希望看到的内容。如果你想让每个月的“第一周”在每个月的第一天开始,那么除了二月份之外,每个月都会有五周(四次中有三次)。

如果你想在某一天开始'周',那么每个月都会有五到六周,除了偶尔的二月。

假设您希望第一个“每月的一周”为第1-7天,第二个为第8-14天等,那么您最好的选择是使用类似

的内容
CASE
    WHEN DATEPART(DAY, PaymentDate) BETWEEN 1 AND 7 THEN 1
    WHEN DATEPART(DAY, PaymentDate) BETWEEN 8 AND 14 THEN 2
    WHEN DATEPART(DAY, PaymentDate) BETWEEN 15 AND 21 THEN 3
    WHEN DATEPART(DAY, PaymentDate) BETWEEN 22 AND 28 THEN 4
    ELSE 5
END

(例如)。

然而,最重要的事情是确切地定义您希望它在每种情况下的行为方式。然后查询可以遵循该。

答案 1 :(得分:1)

感谢您的帮助,干得好: - )

SELECT 
             SUM(Amount) AS 'Amount',
             SUM(COALESCE(Balance,0)) AS 'Balance' ,
             CASE
            WHEN DATEPART(DAY, PaymentDate) BETWEEN 1 AND 7 THEN 1
            WHEN DATEPART(DAY, PaymentDate) BETWEEN 8 AND 14 THEN 2
            WHEN DATEPART(DAY, PaymentDate) BETWEEN 15 AND 21 THEN 3
            WHEN DATEPART(DAY, PaymentDate) BETWEEN 22 AND 28 THEN 4
            ELSE 5
        END   AS MyWeek

        FROM Payment
        WHERE     (MONTH(PaymentDate) = MONTH('2012-09-01'))
        GROUP BY (CASE
            WHEN DATEPART(DAY, PaymentDate) BETWEEN 1 AND 7 THEN 1
            WHEN DATEPART(DAY, PaymentDate) BETWEEN 8 AND 14 THEN 2
            WHEN DATEPART(DAY, PaymentDate) BETWEEN 15 AND 21 THEN 3
            WHEN DATEPART(DAY, PaymentDate) BETWEEN 22 AND 28 THEN 4
            ELSE 5
        END 
        )
        GO

答案 2 :(得分:0)

这就是我写你的查询的方式:

  SELECT DATEPART(MONTH,PaymentDate) AS 'Month',
         datepart(wk,PaymentDate)-datepart(wk,'20120901')+1 AS 'Week #',
         SUM(COALESCE(Amount,0)) AS 'Amount',
         SUM(COALESCE(Balance,0)) AS 'Balance'
    FROM Payment
   WHERE PaymentDate >= '20120901'
     AND PaymentDate <  '20121001'
GROUP BY DATEPART(MONTH,PaymentDate),
         datepart(wk,PaymentDate);

我将PaymentDate过滤器更改为范围,以修复2个错误:
(1)没有考虑到年份 (2)它不是SARGABLE,即因为您在PaymentDate列上执行了某个功能,它会忽略PaymentDate列上的任何索引< / p>

虽然您接受的解决方案只允许5 week #个值,因为它将周数定义为1-7,8-14等,这个允许2012年12月编号如下:

Sun Mon Tue Wed Thu Fri Sat   Week #
                         1     1
 2   3   4   5   6   7   8     2
 9  10  11  12  13  14  15     3
16  17  18  19  20  21  22     4
23  24  25  26  27  28  29     5
30  31                         6