1

可能重复:
TSQL 计算月份的周数

这是我的 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

在此处输入图像描述

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

现在我有两个问题

1)如您所见,它显示的是一年中的第 # 周而不是那个月。

2)它还显示 6 周组而不是 4 组。

我该如何解决。

谢谢。

4

3 回答 3

5

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

我在这里的评论中假设公历。

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

如果您希望“周”从特定的一天开始,那么每个月都会有五到六周,除了偶尔的二月。

假设您希望本月的第一周是第 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

(例如)。

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

于 2012-10-06T15:11:58.483 回答
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
于 2012-10-06T18:49:09.717 回答
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列上的索引

虽然您接受的解决方案只允许 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
于 2012-10-06T22:11:11.823 回答