SQL桶确定年龄分组

时间:2010-01-22 23:02:00

标签: sql sql-server tsql

我有一个包含遗留数据的数据库,用于存储交易并使用“桶”方法来确定帐户余额。我需要一种方法让账龄过期。

表交易
TRANSACTIONID
TransactionType(CHARGE,RECEIPT)

获取当前余额:

SELECT SUM(CASE TransactionTypeId WHEN RECEIPT THEN Amount * -1 ELSE Amount END) CurrentBalance

我需要一种方法来确定过期30,60,90,120等:

帐户当前30 60 90 120+
12345 $ 50.00 $ 0.00 $ 25.00 $ 25.00 $ 0.00

我尝试运行单独的查询并将CHARGE后期限制为大于30,60,90,120,为每个组运行并减去其他组等,但无法获得预期结果。

该表不存储过期的标志,所有余额都是即时计算的。

我错过了一些简单的东西吗?我尝试了网络搜索,但不确定是否有这种类型的SQL查询的术语。

如果有帮助,数据库就是SQL Server。

TIA

2 个答案:

答案 0 :(得分:3)

您可以使用case中的附加条款来过滤掉过去30天内的交易。例如:

SELECT 
    SUM(
        CASE WHEN TransactionTypeId = 'RECEIPT' THEN -Amount 
             ELSE Amount 
    END) as CurrentDue
,   SUM(CASE WHEN datediff(d,PostDate,getdate()) <= 30 THEN 0
             WHEN TransactionTypeId = 'RECEIPT' THEN -Amount 
             ELSE Amount 
    END) as PastDue30
,   ...
FROM Transactions

要排除过去30天的费用,请更换when条款:

,   SUM(CASE WHEN TransactionTypeId = 'RECEIPT' THEN -Amount 
             WHEN datediff(d,PostDate,getdate()) <= 30 THEN 0
             ELSE Amount 
    END) as PastDue30

答案 1 :(得分:0)

这就是我最终得到的,这是我以前所拥有的,但却错过了应付金额为零时的检查,以及检查前一组是否为负值。我不得不添加它们,因为我得到了奇怪的结果,比如说该帐户的服务费用过高,这对前一段时间会产生负面影响。

SELECT
ServiceId,
AmountDue PastDue,
CASE AmountDue WHEN 0 THEN 0 ELSE CASE WHEN AmountDue60 &lt; 0 THEN 0 ELSE AmountDue30 - AmountDue60 END END PastDue30,
CASE AmountDue WHEN 0 THEN 0 ELSE CASE WHEN AmountDue90 &lt; 0 THEN 0 ELSE AmountDue60 - AmountDue90 END END PastDue60,
CASE AmountDue WHEN 0 THEN 0 ELSE CASE WHEN AmountDue120 &lt; 0 THEN 0 ELSE AmountDue90 - AmountDue120 END END PastDue90,
CASE AmountDue WHEN 0 THEN 0 ELSE CASE WHEN AmountDue120 &lt; 0 THEN 0 ELSE AmountDue120 END END PastDue120
FROM
(
    SELECT T.ServiceId,
    SUM(CASE WHEN T.TransactionTypeId = @Receipt THEN T.TAmount * -1 WHEN T.TransactionTypeId = @Charge THEN T.TAmount ELSE 0 END) AmountDue,
    SUM(CASE WHEN T.TransactionTypeId = @Receipt THEN T.TAmount * -1 WHEN T.TransactionTypeId = @Charge THEN CASE WHEN DATEDIFF(D, T.TPostDate, @TPostDate) &gt;=  30 THEN T.TAmount ELSE 0 END ELSE 0 END) AmountDue30,
    SUM(CASE WHEN T.TransactionTypeId = @Receipt THEN T.TAmount * -1 WHEN T.TransactionTypeId = @Charge THEN CASE WHEN DATEDIFF(D, T.TPostDate, @TPostDate) &gt;=  60 THEN T.TAmount ELSE 0 END ELSE 0 END) AmountDue60,
    SUM(CASE WHEN T.TransactionTypeId = @Receipt THEN T.TAmount * -1 WHEN T.TransactionTypeId = @Charge THEN CASE WHEN DATEDIFF(D, T.TPostDate, @TPostDate) &gt;=  90 THEN T.TAmount ELSE 0 END ELSE 0 END) AmountDue90,
    SUM(CASE WHEN T.TransactionTypeId = @Receipt THEN T.TAmount * -1 WHEN T.TransactionTypeId = @Charge THEN CASE WHEN DATEDIFF(D, T.TPostDate, @TPostDate) &gt;= 120 THEN T.TAmount ELSE 0 END ELSE 0 END) AmountDue120
    FROM Transactions T
    WHERE T.AccountId = @AccountId
    GROUP BY T.ServiceId
) AB