【问题标题】:How to achieve the bucket values in SQL?如何在 SQL 中实现桶值?
【发布时间】:2018-07-23 07:08:35
【问题描述】:

我有这样的时间表 (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 字段求和,如下所示

  • Principal_7To30_Days

  • Principal_1To3_Months

  • Principal_3To6_Months

  • Principal_6To12_Months

  • Principal_1To3_Years

通过输入日期

我输入的日期是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

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

【问题讨论】:

    标签: sql sql-server tsql sql-server-2008-r2 ssms-2012


    【解决方案1】:

    我不会使用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子查询,性能会更好。

    【讨论】:

    • @Mar1009 没问题很高兴帮助:)
    猜你喜欢
    • 1970-01-01
    • 2021-07-29
    • 1970-01-01
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 2017-05-21
    • 1970-01-01
    • 2011-09-20
    相关资源
    最近更新 更多