2017-09-06 3 views
3

J'essaie de garder une trace d'une somme mobile calculée à l'aide des données de l'année précédente.Utilisation de SQL Over Statement avec une somme cumulée

Actuellement, j'ai ce que mon SQL:

SELECT lngTIMEID as Id, 
     lngEMPID as EmployeeId, 
     dtmdateapp AS [Date], 
     stroccur AS [Value], 
     (SELECT Sum(stroccur) 
     FROM [Attendance].[dbo].timeuse a 
     WHERE a.dtmdateapp between DateAdd(d, -366, d.dtmdateapp) 
       AND d.dtmDATEAPP 
       AND a.lngempid = d.lngempid) AS Total 
FROM [Attendance].[dbo].[timeuse] d 
     WHERE lngEMPID = 1844140 AND absence = 'Unscheduled' AND lngRID IN (1,2,3,4,5,7,8,9,10,11,12,13,14) 

Ce qui ramène un résultat comme celui-ci:

+--------+------------+-----------+-------+-------+ 
| Id | EmployeeId | Date | Value | Total | 
+--------+------------+-----------+-------+-------+ 
| 330435 | 1844140 | 4/17/2017 | 0.25 | 0.25 | 
| 330849 | 1844140 | 4/19/2017 | 0.25 | 0.5 | 
| 331108 | 1844140 | 4/20/2017 | 0.25 | 0.75 | 
| 331641 | 1844140 | 4/24/2017 | 0.25 |  1 | 
| 331736 | 1844140 | 4/25/2017 | 0.25 | 1.25 | 
| 333761 | 1844140 | 5/5/2017 | 0.25 | 1.5 | 
| 336080 | 1844140 | 5/17/2017 |  1 | 2.5 | 
| 349752 | 1844140 | 8/2/2017 | 0.25 |  3 | <--- this should be 2.75 
| 350994 | 1844140 | 8/9/2017 |  1 |  4 | 
| 351426 | 1844140 | 8/11/2017 | 0.25 | 4.25 | 
| 352132 | 1844140 | 8/15/2017 | 0.5 | 4.75 | 
| 354236 | 1844140 | 8/25/2017 | 0.25 |  5 | 
| 355580 | 1844140 | 8/29/2017 | 0.25 | 5.25 | 
| 355650 | 1844140 | 9/5/2017 | 0.25 | 5.5 | 
+--------+------------+-----------+-------+-------+ 

L'idée est qu'il boucle à travers toutes les occurrences et résumer la toutes les occurrences antérieures qui se produisent dans l'année suivant la date actuelle.

Avec mon code actuel, il y a un problème avec le calcul où les coups totaux 3.

Je voudrais utiliser le SQL Plus, car il calcule déclaration correctement mais je ne suis pas sûr de savoir comment l'utiliser avec le roulement 1 an calendrier. Voici ce que je:

SELECT lngTIMEID as Id, 
     lngEMPID as EmployeeId, 
     dtmdateapp AS [Date], 
     stroccur AS [Value], 
     sum(strOCCUR) OVER(ORDER BY dtmdateapp ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as [Total] 
FROM [Attendance].[dbo].[timeuse] d 
     WHERE lngEMPID = 1844140 AND absence = 'Unscheduled' AND lngRID IN (1,2,3,4,5,7,8,9,10,11,12,13,14) 

et me donne le bon résultat parce que ces données se produisent tous dans la même année, mais il ne fonctionnera pas pour le roulement délai de 1 an:

+--------+------------+-----------+-------+-------+ 
| Id | EmployeeId | Date | Value | Total | 
+--------+------------+-----------+-------+-------+ 
| 330435 | 1844140 | 4/17/2017 | 0.25 | 0.25 | 
| 330849 | 1844140 | 4/19/2017 | 0.25 | 0.5 | 
| 331108 | 1844140 | 4/20/2017 | 0.25 | 0.75 | 
| 331641 | 1844140 | 4/24/2017 | 0.25 |  1 | 
| 331736 | 1844140 | 4/25/2017 | 0.25 | 1.25 | 
| 333761 | 1844140 | 5/5/2017 | 0.25 | 1.5 | 
| 336080 | 1844140 | 5/17/2017 |  1 | 2.5 | 
| 349752 | 1844140 | 8/2/2017 | 0.25 | 2.75 | 
| 350994 | 1844140 | 8/9/2017 |  1 | 3.75 | 
| 351426 | 1844140 | 8/11/2017 | 0.25 |  4 | 
| 352132 | 1844140 | 8/15/2017 | 0.5 | 4.5 | 
| 354236 | 1844140 | 8/25/2017 | 0.25 | 4.75 | 
| 355580 | 1844140 | 8/29/2017 | 0.25 |  5 | 
| 355650 | 1844140 | 9/5/2017 | 0.25 | 5.25 | 
+--------+------------+-----------+-------+-------+ 

Comment puis-je ajouter le cadre temporel de 1 an dans l'instruction Over dans MS SQL?

+1

Ce problème a été discuté en détail sur dba.se: [Plage de dates en utilisant les fonctions de roulement somme de fenêtre] (https://dba.stackexchange.com/q/114403/57105) –

+2

Je pense que votre original corrélé la sous-requête devrait fonctionner, si vous ajoutez les mêmes clauses à la sous-requête que votre requête principale (absence = 'Unscheduled' etc). –

+0

Merci @JamesCasey, j'ai juste négligé cela. Merci pour l'aide cela a fonctionné – Aaron

Répondre

1

Comme James l'a mentionné, votre sous-requête d'origine devrait fonctionner. Je l'ai testé sur mon environnement et il renvoie un résultat correct.

WITH tu AS ( 
    SELECT * 
    FROM [Attendance].[dbo].[timeuse] d 
    WHERE lngEMPID = 1844140 AND absence = 'Unscheduled' AND lngRID IN (1,2,3,4,5,7,8,9,10,11,12,13,14) 
) 
SELECT lngTIMEID as Id, 
     lngEMPID as EmployeeId, 
     dtmdateapp AS [Date], 
     stroccur AS [Value], 
     (SELECT Sum(stroccur) 
     FROM tu a 
     WHERE a.dtmdateapp between DateAdd(d, -366, d.dtmdateapp) 
       AND d.dtmDATEAPP 
       AND a.lngempid = d.lngempid) AS Total 
FROM tu d 
+0

Le PO a demandé comment utiliser la clause 'OVER', pas si l'original fonctionne. La raison est évidente - la requête est un nettoyant * lot *. Selon les options utilisées, il peut être beaucoup plus rapide –