如何获得SQL中的桶值?

How to achieve the bucket values in SQL?

我有这样的时间表 table (table name = testSch)

ID  Amount  scheduleDate     
1   7230.00  2018-07-13  
1   7272.00  2018-07-27  
1   7314.00  2018-08-10  
1   7356.00  2018-08-24  
1   7398.00  2018-09-07  
1   7441.00  2018-09-21  
1   7439.00  2018-10-08  
1   7526.00  2018-10-22  
1   7570.00  2018-11-05  
1   7613.00  2018-11-19  
1   5756.00  2018-12-03  

我需要根据特定的存储桶值对 Amount 字段求和,如下所示

通过输入日期

我输入的日期是2018-07-09下面是我的查询;

;with cteSchedule as (
select *,DATEDIFF(DAY,'20180709',scheduleDate) as datedifference, 
DATEDIFF(MONTH,'20180709',scheduleDate) as monthdifference from testSch)
select  ISNULL((SELECT SUM(cteSchedule.Amount) 
    FROM cteSchedule 
    WHERE cteSchedule.datedifference <7),0)  AS Principal_0To7_Days, 

    ISNULL((SELECT SUM(cteSchedule.Amount) 
    FROM cteSchedule 
    WHERE cteSchedule.datedifference>=7 and cteSchedule.datedifference<30),0)  
    AS Principal_7To30_Days,

    ISNULL((SELECT SUM(cteSchedule.Amount) 
    FROM cteSchedule 
    WHERE cteSchedule.datedifference>=30 and cteSchedule.datedifference<90),0)  AS Principal_1To3_Months,

    ISNULL((SELECT SUM(cteSchedule.Amount) 
    FROM cteSchedule 
    WHERE cteSchedule.datedifference>=90 and cteSchedule.datedifference<180),0)  AS Principal_3To6_Months,

    ISNULL((SELECT SUM(cteSchedule.Amount) 
    FROM cteSchedule 
    WHERE cteSchedule.datedifference>=180 and cteSchedule.datedifference<365),0)  AS Principal_6To12_Months

下面是我的输出

Principal_0To7_Days Principal_7To30_Days    Principal_1To3_Months Principal_3To6_Months Principal_6To12_Months  
7230.00             7272.00                 29509.00              35904.00       0.00   

但正确的输出应该是

    Principal_0To7_Days Principal_7To30_Days    Principal_1To3_Months Principal_3To6_Months Principal_6To12_Months  
7230.00             7272.00                     36948.00              28465.00       0.00

所以问题是我得到的 Principal_1To3_MonthsPrincipal_3To6_Months 的值是错误的,当我问我的客户他们如何在他们的遗留系统中计算这个,他们回答说他们通过添加月数而不是天数来使用 +-months 来计算。因此,如果今天是 2018-07-09 + 3 个月,我们将得到 2018-10-09。

所以我在我的 cte 查询中使用了月份差异,如下所示

 DATEDIFF(MONTH,'20180709',scheduleDate) as monthdifference

并在我的整体查询中使用它,如下所示

ISNULL((SELECT SUM(cteSchedule.Amount) 
    FROM cteSchedule 
    WHERE cteSchedule.monthdifference>=1 and cteSchedule.monthdifference<=3),0)  AS Principal_1To3_Months

但是这次我也得到了与我第一个输出中提到的相同的值。 有人可以指出我的错误在哪里以及如何实现正确输出中提到的这些值

我不会用DATEDIFF来计算daymonth天数的差异,因为有的月份有31天,有的月份有30天。

因此,计算出的差异天数不准确。

我会使用 DATEADD 而不是 DATEDIFF 来完成条件。

;with cteSchedule as (
select *,'20180709' compareDay
from testSch
)
SELECT Sum(CASE 
            WHEN t.scheduleDate < DATEADD(day, 7, compareDay) 
            THEN t.amount
            ELSE 0
        END) AS  Principal_0To7_Days,
        Sum(CASE 
            WHEN t.scheduleDate >=DATEADD(day, 7, compareDay) AND t.scheduleDate < DATEADD(day, 30, compareDay) 
            THEN t.amount
            ELSE 0
        END) AS Principal_7To30_Days,
        Sum(CASE 
            WHEN t.scheduleDate >=DATEADD(month,1,compareDay) AND t.scheduleDate < DATEADD(month,3,compareDay)
            THEN t.amount
            ELSE 0
        END) AS Principal_1To3_Months,
        Sum(CASE 
            WHEN  t.scheduleDate >=DATEADD(month,3,compareDay) AND t.scheduleDate < DATEADD(month,6,compareDay)
            THEN t.amount
            ELSE 0
        END) AS Principal_3To6_Months,
        Sum(CASE 
            WHEN t.scheduleDate >=DATEADD(month,6,compareDay) AND t.scheduleDate < DATEADD(month,12,compareDay)
            THEN t.amount
            ELSE 0
        END) AS Principal_6To12_Months
from cteSchedule t

SQLFiddle

[结果]:

| Principal_0To7_Days | Principal_7To30_Days | Principal_1To3_Months | Principal_3To6_Months | Principal_6To12_Months |
|---------------------|----------------------|-----------------------|-----------------------|------------------------|
|                7230 |                 7272 |                 36948 |                 28465 |                      0 |

备注

您可以将 CASE WHENSUM 一起使用 聚合函数代替select子查询,性能会更好