2010-01-22 4 views
3

J'ai une base de données avec des données héritées qui stocke des transactions et utilise une méthode "seau" pour déterminer les soldes de compte. J'ai besoin d'un moyen de vieillir en raison des comptes.Les segments SQL déterminent le groupe d'âge

Tableau Transactions
TransactionId
TransactionType (CHARGE, REÇU)
Montant
POSTDATE

Pour obtenir l'équilibre actuel:

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

je besoin d'un moyen de déterminer échues 30, 60, 90, 120, etc:

Compte C dusyst 30 60 90 120+
12345 $ 50,00 0,00 $ 25,00 $ 25,00 $ 0,00 $

J'ai essayé de lancer des requêtes distinctes et limiter la CHARGE postdate à plus de 30,60,90,120, en cours d'exécution pour chaque groupe et en soustrayant les autres, etc, mais ne peux pas les résultats attendus.

La table ne stocke pas de drapeau pour les arriérés, tous les soldes sont calculés à la volée.

Ai-je oublié quelque chose de simple? J'ai essayé une recherche de réseau, mais je ne sais pas s'il existe un terme pour ce type de requête sql.

La base de données est SQL Server si cela vous aide.

TIA

Répondre

2

Vous pouvez utiliser une clause supplémentaire dans le case pour filtrer les transactions des 30 derniers jours. Par exemple:

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 

Pour simplement exclure les frais des 30 derniers jours, échanger les when clauses:

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

@Andomar - reçus qui sont arrivés récemment (à savoir dans les 30 derniers jours) devraient être soustraites du montant PastDue30 - peut-être juste exclure la _charges_ au cours des 30 derniers jours? - Ils ne sont pas encore en retard. –

+0

@martin clayton: Donc, le "dû" est-il vraiment des frais de 30 jours qui n'ont pas encore été payés? Vous pouvez calculer cela en SQL en échangeant les clauses 'when'. Je vais l'ajouter à la réponse – Andomar

+0

pense ainsi, et belle solution, +1. –

0

C'est ce que j'ai fini avec quelque chose que je devais partir avant, mais il manquait les vérifications pour savoir quand le montant dû est nul, ainsi que pour vérifier si le groupe précédent avait une valeur négative. Je devais les ajouter parce que je recevais des résultats étranges, disons si le compte était trop payé pour un service, ce qui aurait un négatif dû pour la période précédente.

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