如何使用 CASE 语句计算 SQL 服务器中的存储桶值
How to calculate bucket values in SQL server using CASE statement
我有一个像这样的 'Schedule' table 帐户计划 = 'Acctxyz':
Account DueDate Amount
Acctxyz 2018-03-09 3049.00
Acctxyz 2018-03-23 17857.00
Acctxyz 2018-04-06 17949.00
Acctxyz 2018-04-20 18042.00
Acctxyz 2018-05-04 18135.00
Acctxyz 2018-05-18 18229.00
Acctxyz 2018-06-01 18324.00
Acctxyz 2018-06-15 18419.00
Acctxyz 2018-06-29 18514.00
我的输入日期应该是 2017-07-09,输出应该是 Account 列,其他四个字段的金额应该根据与我的输入日期和截止日期的日期差异在四个桶中汇总,如下所示;
Account Late Arrears SeriousArrears NonPerforming
Acctxyz #### #### #### ####
- 延迟应为日期差为 2 和 30 的金额之和
- 欠款应为日期差为 31 和 60 的金额之和
- SeriousArrears 应该是日期差异为 60 和 90 的金额之和
- 不良应为日期差异 >= 91 的金额之和
下面是我所做的;
declare @Rundate date = '20180709'
select Account,
CASE WHEN DATEDIFF(D,@Rundate,DueDate) BETWEEN -2 AND -30 THEN SUM(Amount) ELSE 0 END as Late,
CASE WHEN DATEDIFF(D,@Rundate,DueDate) BETWEEN -31 AND -60 THEN SUM(Amount) ELSE 0 END as Arrears,
CASE WHEN DATEDIFF(D,@Rundate,DueDate) BETWEEN -61 AND -90 THEN SUM(Amount) ELSE 0 END as SeriousArrears,
CASE WHEN DATEDIFF(D,@Rundate,DueDate) >= -91 THEN SUM(Amount) ELSE 0 END as NonPerforming
from Schedule
group by Acct,DueDateKey
我得到一个包含九行且所有字段都为零的输出。
非常感谢如何实现异常输出,请指出我哪里出错了。
BETWEEN -2 AND -30
表示大于-2小于-30的数。有none。您必须小心使用带有负值的 between 。更改您的 DATEDIFF
以获得正日差。
试试这个:
SELECT Account ,
CASE WHEN DATEDIFF(D, DueDate, @Rundate)
BETWEEN 2 AND 30 THEN SUM(Amount)
ELSE 0
END AS Late ,
CASE WHEN DATEDIFF(D, DueDate, @Rundate)
BETWEEN 31 AND 60 THEN SUM(Amount)
ELSE 0
END AS Arrears ,
CASE WHEN DATEDIFF(D, DueDate, @Rundate)
BETWEEN 61 AND 90 THEN SUM(Amount)
ELSE 0
END AS SeriousArrears ,
CASE WHEN DATEDIFF(D, DueDate, @Rundate) >= 91 THEN SUM(Amount)
ELSE 0
END AS NonPerforming
FROM Schedule
GROUP BY Account, DueDate
更新 如果您需要单行作为结果集:
CREATE TABLE #Schedule
(
Account VARCHAR(10) ,
DueDate DATE ,
Amount DECIMAL(10, 2)
);
INSERT INTO #Schedule ( Account ,
DueDate ,
Amount )
VALUES ( 'Acctxyz', '2018-03-09', 3049.00 ) ,
( 'Acctxyz', '2018-03-23', 17857.00 ) ,
( 'Acctxyz', '2018-04-06', 17949.00 ) ,
( 'Acctxyz', '2018-04-20', 18042.00 ) ,
( 'Acctxyz', '2018-05-04', 18135.00 ) ,
( 'Acctxyz', '2018-05-18', 18229.00 ) ,
( 'Acctxyz', '2018-06-01', 18324.00 ) ,
( 'Acctxyz', '2018-06-15', 18419.00 ) ,
( 'Acctxyz', '2018-06-29', 18514.00 );
DECLARE @Rundate DATE = '20180709';
SELECT t.Account ,
SUM(Late) AS Late ,
SUM(Arrears) AS Late ,
SUM(SeriousArrears) AS SeriousArrears ,
SUM(NonPerforming) AS NonPerforming
FROM ( SELECT Account ,
CASE WHEN DATEDIFF(D, DueDate, @Rundate)
BETWEEN 2 AND 30 THEN SUM(Amount)
ELSE 0
END AS Late ,
CASE WHEN DATEDIFF(D, DueDate, @Rundate)
BETWEEN 31 AND 60 THEN SUM(Amount)
ELSE 0
END AS Arrears ,
CASE WHEN DATEDIFF(D, DueDate, @Rundate)
BETWEEN 61 AND 90 THEN SUM(Amount)
ELSE 0
END AS SeriousArrears ,
CASE WHEN DATEDIFF(D, DueDate, @Rundate) >= 91 THEN
SUM(Amount)
ELSE 0
END AS NonPerforming
FROM #Schedule
GROUP BY Account ,
DueDate ) t
GROUP BY t.Account;
DROP TABLE #Schedule;
结果:
+---------+----------+----------+----------------+---------------+
| Account | Late | Late | SeriousArrears | NonPerforming |
+---------+----------+----------+----------------+---------------+
| Acctxyz | 36933.00 | 36553.00 | 36177.00 | 38855.00 |
+---------+----------+----------+----------------+---------------+
由于负值,您 BETWEEN
的操作不正确。检查以下内容:
declare @Rundate date = '20180709'
select Account,DATEDIFF(D,@Rundate,DueDate),
Sum(CASE WHEN DATEDIFF(D,@Rundate,DueDate) BETWEEN -30 AND -2 THEN Amount ELSE 0 END) as Late,
Sum(CASE WHEN DATEDIFF(D,@Rundate,DueDate) BETWEEN -60 AND -31 THEN Amount ELSE 0 END) as Arrears,
Sum(CASE WHEN DATEDIFF(D,@Rundate,DueDate) BETWEEN -90 AND -61 THEN Amount ELSE 0 END) as SeriousArrears,
Sum(CASE WHEN DATEDIFF(D,@Rundate,DueDate) <= -91 THEN Amount ELSE 0 END) as NonPerforming
from #Schedule
group by Account,DueDate
如Arvo所说
这可能就是您正在寻找的解决方案
架构:
SELECT * INTO #Schedule FROM (
SELECT 'Acctxyz' Account,'2018-03-09' DueDate,3049.00 Amount UNION ALL
SELECT 'Acctxyz','2018-03-23',17857.00 UNION ALL
SELECT 'Acctxyz','2018-04-06',17949.00 UNION ALL
SELECT 'Acctxyz','2018-04-20',18042.00 UNION ALL
SELECT 'Acctxyz','2018-05-04',18135.00 UNION ALL
SELECT 'Acctxyz','2018-05-18',18229.00 UNION ALL
SELECT 'Acctxyz','2018-06-01',18324.00 UNION ALL
SELECT 'Acctxyz','2018-06-15',18419.00 UNION ALL
SELECT 'Acctxyz','2018-06-29',18514.00
)A
查询:
Declare @Rundate date = '20180709'
select Account,
SUM(CASE WHEN DATEDIFF(D,@Rundate,DueDate) BETWEEN -30 AND -2 THEN Amount ELSE 0 END) as Late,
SUM(CASE WHEN DATEDIFF(D,@Rundate,DueDate) BETWEEN -60 AND -31 THEN Amount ELSE 0 END) as Arrears,
SUM(CASE WHEN DATEDIFF(D,@Rundate,DueDate) BETWEEN -90 AND -61 THEN Amount ELSE 0 END) as SeriousArrears,
SUM(CASE WHEN DATEDIFF(D,@Rundate,DueDate) >= -91 THEN Amount ELSE 0 END) as NonPerforming
from #Schedule
group by Account
结果:
Account Late Arrears SeriousArrears NonPerforming
Acctxyz 36933.00 36553.00 36177.00 109663.00
感谢您的所有建议,它真的很有帮助,我从您的所有建议中得出以下答案;
select Account,
sum (case WHEN DATEDIFF(D, DueDate, @Rundate) BETWEEN 2 AND 30 THEN Amount else 0 end) as late,
sum (case WHEN DATEDIFF(D, DueDate, @Rundate) BETWEEN 31 AND 60 THEN Amount else 0 end) as Arrears,
sum (case WHEN DATEDIFF(D, DueDate, @Rundate) BETWEEN 61 AND 90 THEN Amount else 0 end) as SeriousArrears,
sum (case WHEN DATEDIFF(D, DueDate, @Rundate) >= 91 THEN Amount else 0 end) as NonPerforming
from #schedule
group by Account
我有一个像这样的 'Schedule' table 帐户计划 = 'Acctxyz':
Account DueDate Amount
Acctxyz 2018-03-09 3049.00
Acctxyz 2018-03-23 17857.00
Acctxyz 2018-04-06 17949.00
Acctxyz 2018-04-20 18042.00
Acctxyz 2018-05-04 18135.00
Acctxyz 2018-05-18 18229.00
Acctxyz 2018-06-01 18324.00
Acctxyz 2018-06-15 18419.00
Acctxyz 2018-06-29 18514.00
我的输入日期应该是 2017-07-09,输出应该是 Account 列,其他四个字段的金额应该根据与我的输入日期和截止日期的日期差异在四个桶中汇总,如下所示;
Account Late Arrears SeriousArrears NonPerforming
Acctxyz #### #### #### ####
- 延迟应为日期差为 2 和 30 的金额之和
- 欠款应为日期差为 31 和 60 的金额之和
- SeriousArrears 应该是日期差异为 60 和 90 的金额之和
- 不良应为日期差异 >= 91 的金额之和
下面是我所做的;
declare @Rundate date = '20180709'
select Account,
CASE WHEN DATEDIFF(D,@Rundate,DueDate) BETWEEN -2 AND -30 THEN SUM(Amount) ELSE 0 END as Late,
CASE WHEN DATEDIFF(D,@Rundate,DueDate) BETWEEN -31 AND -60 THEN SUM(Amount) ELSE 0 END as Arrears,
CASE WHEN DATEDIFF(D,@Rundate,DueDate) BETWEEN -61 AND -90 THEN SUM(Amount) ELSE 0 END as SeriousArrears,
CASE WHEN DATEDIFF(D,@Rundate,DueDate) >= -91 THEN SUM(Amount) ELSE 0 END as NonPerforming
from Schedule
group by Acct,DueDateKey
我得到一个包含九行且所有字段都为零的输出。
非常感谢如何实现异常输出,请指出我哪里出错了。
BETWEEN -2 AND -30
表示大于-2小于-30的数。有none。您必须小心使用带有负值的 between 。更改您的 DATEDIFF
以获得正日差。
试试这个:
SELECT Account ,
CASE WHEN DATEDIFF(D, DueDate, @Rundate)
BETWEEN 2 AND 30 THEN SUM(Amount)
ELSE 0
END AS Late ,
CASE WHEN DATEDIFF(D, DueDate, @Rundate)
BETWEEN 31 AND 60 THEN SUM(Amount)
ELSE 0
END AS Arrears ,
CASE WHEN DATEDIFF(D, DueDate, @Rundate)
BETWEEN 61 AND 90 THEN SUM(Amount)
ELSE 0
END AS SeriousArrears ,
CASE WHEN DATEDIFF(D, DueDate, @Rundate) >= 91 THEN SUM(Amount)
ELSE 0
END AS NonPerforming
FROM Schedule
GROUP BY Account, DueDate
更新 如果您需要单行作为结果集:
CREATE TABLE #Schedule
(
Account VARCHAR(10) ,
DueDate DATE ,
Amount DECIMAL(10, 2)
);
INSERT INTO #Schedule ( Account ,
DueDate ,
Amount )
VALUES ( 'Acctxyz', '2018-03-09', 3049.00 ) ,
( 'Acctxyz', '2018-03-23', 17857.00 ) ,
( 'Acctxyz', '2018-04-06', 17949.00 ) ,
( 'Acctxyz', '2018-04-20', 18042.00 ) ,
( 'Acctxyz', '2018-05-04', 18135.00 ) ,
( 'Acctxyz', '2018-05-18', 18229.00 ) ,
( 'Acctxyz', '2018-06-01', 18324.00 ) ,
( 'Acctxyz', '2018-06-15', 18419.00 ) ,
( 'Acctxyz', '2018-06-29', 18514.00 );
DECLARE @Rundate DATE = '20180709';
SELECT t.Account ,
SUM(Late) AS Late ,
SUM(Arrears) AS Late ,
SUM(SeriousArrears) AS SeriousArrears ,
SUM(NonPerforming) AS NonPerforming
FROM ( SELECT Account ,
CASE WHEN DATEDIFF(D, DueDate, @Rundate)
BETWEEN 2 AND 30 THEN SUM(Amount)
ELSE 0
END AS Late ,
CASE WHEN DATEDIFF(D, DueDate, @Rundate)
BETWEEN 31 AND 60 THEN SUM(Amount)
ELSE 0
END AS Arrears ,
CASE WHEN DATEDIFF(D, DueDate, @Rundate)
BETWEEN 61 AND 90 THEN SUM(Amount)
ELSE 0
END AS SeriousArrears ,
CASE WHEN DATEDIFF(D, DueDate, @Rundate) >= 91 THEN
SUM(Amount)
ELSE 0
END AS NonPerforming
FROM #Schedule
GROUP BY Account ,
DueDate ) t
GROUP BY t.Account;
DROP TABLE #Schedule;
结果:
+---------+----------+----------+----------------+---------------+
| Account | Late | Late | SeriousArrears | NonPerforming |
+---------+----------+----------+----------------+---------------+
| Acctxyz | 36933.00 | 36553.00 | 36177.00 | 38855.00 |
+---------+----------+----------+----------------+---------------+
由于负值,您 BETWEEN
的操作不正确。检查以下内容:
declare @Rundate date = '20180709'
select Account,DATEDIFF(D,@Rundate,DueDate),
Sum(CASE WHEN DATEDIFF(D,@Rundate,DueDate) BETWEEN -30 AND -2 THEN Amount ELSE 0 END) as Late,
Sum(CASE WHEN DATEDIFF(D,@Rundate,DueDate) BETWEEN -60 AND -31 THEN Amount ELSE 0 END) as Arrears,
Sum(CASE WHEN DATEDIFF(D,@Rundate,DueDate) BETWEEN -90 AND -61 THEN Amount ELSE 0 END) as SeriousArrears,
Sum(CASE WHEN DATEDIFF(D,@Rundate,DueDate) <= -91 THEN Amount ELSE 0 END) as NonPerforming
from #Schedule
group by Account,DueDate
如Arvo所说
这可能就是您正在寻找的解决方案
架构:
SELECT * INTO #Schedule FROM (
SELECT 'Acctxyz' Account,'2018-03-09' DueDate,3049.00 Amount UNION ALL
SELECT 'Acctxyz','2018-03-23',17857.00 UNION ALL
SELECT 'Acctxyz','2018-04-06',17949.00 UNION ALL
SELECT 'Acctxyz','2018-04-20',18042.00 UNION ALL
SELECT 'Acctxyz','2018-05-04',18135.00 UNION ALL
SELECT 'Acctxyz','2018-05-18',18229.00 UNION ALL
SELECT 'Acctxyz','2018-06-01',18324.00 UNION ALL
SELECT 'Acctxyz','2018-06-15',18419.00 UNION ALL
SELECT 'Acctxyz','2018-06-29',18514.00
)A
查询:
Declare @Rundate date = '20180709'
select Account,
SUM(CASE WHEN DATEDIFF(D,@Rundate,DueDate) BETWEEN -30 AND -2 THEN Amount ELSE 0 END) as Late,
SUM(CASE WHEN DATEDIFF(D,@Rundate,DueDate) BETWEEN -60 AND -31 THEN Amount ELSE 0 END) as Arrears,
SUM(CASE WHEN DATEDIFF(D,@Rundate,DueDate) BETWEEN -90 AND -61 THEN Amount ELSE 0 END) as SeriousArrears,
SUM(CASE WHEN DATEDIFF(D,@Rundate,DueDate) >= -91 THEN Amount ELSE 0 END) as NonPerforming
from #Schedule
group by Account
结果:
Account Late Arrears SeriousArrears NonPerforming
Acctxyz 36933.00 36553.00 36177.00 109663.00
感谢您的所有建议,它真的很有帮助,我从您的所有建议中得出以下答案;
select Account,
sum (case WHEN DATEDIFF(D, DueDate, @Rundate) BETWEEN 2 AND 30 THEN Amount else 0 end) as late,
sum (case WHEN DATEDIFF(D, DueDate, @Rundate) BETWEEN 31 AND 60 THEN Amount else 0 end) as Arrears,
sum (case WHEN DATEDIFF(D, DueDate, @Rundate) BETWEEN 61 AND 90 THEN Amount else 0 end) as SeriousArrears,
sum (case WHEN DATEDIFF(D, DueDate, @Rundate) >= 91 THEN Amount else 0 end) as NonPerforming
from #schedule
group by Account