2017-08-22 10 views
1

J'essaie d'écrire une vue dans SQL Server 2012 où je calcule la somme mobile de 30 jours pour un ensemble de transactions.La somme mobile de 30 jours à l'aide de la clause OVER dans SQL Server 2012

scénario actuel:

SELECT CustNo, TransactionDate, TransactionAmount, SUM(TransactionAmount) 
     OVER (PARTITION BY CustNo ORDER BY TransactionDate) AS MovingAmount 
FROM   dbo.TransactionData 

ensemble de données:

CustNo  TransactionDate TransactionAmount 
1111  5/7/2015   3,000 
1111  5/14/2015   3,000 
2222  5/17/2015   100 
1111  5/21/2015   3,000 
1111  5/28/2015   3,000 
3333  5/31/2015   11,000 
1111  6/10/2015   3,000 

Résultat attendu:

CustNo  TransactionDate TransactionAmount MovingAmount 
1111  5/7/2015   3,000    12,000 
1111  5/14/2015   3,000    12,000 
2222  5/17/2015   100     100 
1111  5/21/2015   3,000    9,000 
1111  5/28/2015   3,000    6,000 
3333  5/31/2015   11,000    11,000 
1111  6/10/2015   3,000    3,000 

Autres tentatives:

SELECT CustNo, TransactionDate, TransactionAmount, SUM(TransactionAmount) 
     OVER (PARTITION BY CustomerNumber ORDER BY TransactionDate, 
     BETWEEN TransactionDate AND DATEADD(day, 30, TransactionDate)) 
     AS MovingAmount 
FROM   dbo.TransactionData 
+0

Je ne comprends pas la logique que vous appliquez pour obtenir les résultats attendus – Horaciux

+0

Pourquoi le montant mobile est 12 000 à la date de transaction 07/05/2015? Il devrait être 3000 à partir de cet exemple de données –

+0

Zohar, il agrège la somme des transactions sur 30 jours, donc il ajoute 3000 sur 5/7, 3000 le 5/14, 3000 le 5/21 et 3000 le 5/28. –

Répondre

1

Je suppose que le 12 000 dans la première rangée de votre résultat désiré est une faute de frappe, et il devrait être 3000. Si je ne me trompe pas, votre première requête semble fonctionner très bien, il est juste difficile de voir sans order by à toute requête:

Créer et remplir le tableau d'échantillons (S'il vous plaît nous sauver cette étape dans votre les questions futures)

CREATE TABLE TransactionData 
(
    CustNo int, 
    TransactionDate date, 
    TransactionAmount int 
) 

INSERT INTO TransactionData(CustNo, TransactionDate, TransactionAmount) VALUES 
(1111, '2015-05-07', 3000), 
(1111, '2015-05-14', 3000), 
(2222, '2015-05-17', 100), 
(1111, '2015-05-21', 3000), 
(1111, '2015-05-28', 3000), 
(3333, '2015-05-31', 11000), 
(1111, '2015-06-10', 3000) 

Voulez-vous profiter de l'interprétation Tab Alleman de la question, il ne peut pas se faire avec la clause sur, vous devez utiliser une sous requête en corrélation:

SELECT CustNo, 
     TransactionDate, 
     TransactionAmount, 
     (SELECT SUM(TransactionAmount) 
     FROM dbo.TransactionData t1 
     WHERE t1.CustNo = t0.CustNo 
     AND t1.TransactionDate >= t0.TransactionDate 
     AND t1.TransactionDate <= DATEADD(DAY, 30, t0.TransactionDate)) As MovingAmount 
FROM dbo.TransactionData t0 
ORDER BY CustNo, TransactionDate 

Résultats:

CustNo TransactionDate   TransactionAmount MovingAmount 
1111 07.05.2015 00:00:00  3000    12000 
1111 14.05.2015 00:00:00  3000    12000 
1111 21.05.2015 00:00:00  3000    9000 
1111 28.05.2015 00:00:00  3000    6000 
1111 10.06.2015 00:00:00  3000    3000 
2222 17.05.2015 00:00:00  100     100 
3333 31.05.2015 00:00:00  11000    11000 

You can see a live demo on rextester.

+0

Sauf que cela sera SUM sur l'ensemble du jeu de données et pas seulement 30 jours en mouvement. C'est pourquoi vous avez 15000 dans la cinquième rangée, où, selon votre interprétation, vous devriez seulement avoir 12000, puisque la transaction du 5 juillet est en dehors de la fenêtre de 30 jours. Je pense aussi que votre interprétation doit inclure 30 jours passés, où OP veut 30 jours d'avenir. Cela expliquerait le résultat souhaité par OP. –

+0

@ TabAlleman Je suppose que vous avez raison et j'ai simplement mal compris la question. –

+0

Édité ma réponse. –