0
votes

SQL- somme cumulative basée sur la condition

J'ai un scénario dans lequel je dois calculer le compteur en fonction des données ci-dessous. Si le statut est un, B, C, C de compteur doit être 0 qui fonctionne bien.

Si l'état est un compteur de D devrait faire une somme cumulative à l'exception que si l'état est modifié entre (comme en 201907), le compteur Devrait réinitialiser à nouveau et la somme devrait recommencer avec 1,2,3 et ainsi de suite. Toute aide possible est appréciée sur la même chose.

entrée - 3 colonnes - Customer_no, date, état xxx

sortie attendu - colonnes d'entrée + Colonne de comptoir xxx

exemple de données

merci


5 commentaires

Votre question dépend d'une commande des colonnes, mais vous n'avez pas spécifié de commande.


Quelle est votre production attendue ici?


Si vos données ne contiennent pas une clé toujours ascendante, cela est impossible à réaliser.


Toutes mes excuses, les données ont également une colonne clé. Son format mensuel d'une année comme 201901, 201902 201903, 201904 n ainsi de suite pour 12 enregistrements. La sortie est la colonne de comptoir et elle doit réinitialiser la somme si l'état passe à D - comme indiqué dans l'image.


@Ankurnagpal Il serait plus utile que vous modifiez la question et fournissez plus de contexte concernant la sortie attendue et l'entrée révisée que vous dites tout dans le format de texte.


3 Réponses :


0
votes

Ceci est une variante d'un problème de lacunes et de îles. Pour cette incarnation particulière, vous pouvez identifier les îles en comptant le nombre d'états non-d avant une ligne donnée.

Après avoir identifié les groupes, utilisez case et Row_Number () : xxx


1 commentaires

Merci, cela fonctionne parfaitement bien :) Beaucoup apprécié vos intrants



0
votes

Il s'agit d'une approche similaire que Gordon utilise des CTES et Row_Number CODE> pour faire d'abord les îles, puis il n'y a qu'une seule ligne dans cette île à l'aide d'un compteur vitré et un cas code> Expression:

WITH Grps AS(
    SELECT ID,
           CUSTOMER_NO,
           [STATUS],
           ROW_NUMBER() OVER (PARTITION BY CUSTOMER_NO ORDER BY ID) -
           ROW_NUMBER() OVER (PARTITION BY CUSTOMER_NO, [STATUS] ORDER BY ID) AS Grp
    FROM (VALUES(1,1234,'A'),
                (2,1234,'B'),
                (3,1234,'C'),
                (4,1234,'D'),
                (5,1234,'D'),
                (6,1234,'D'),
                (7,1234,'C'),
                (8,1234,'D'),
                (9,1234,'D'),
                (10,1234,'D'),
                (11,1234,'D'))V(ID,CUSTOMER_NO,[STATUS]))
SELECT ID,
       CUSTOMER_NO,
       [STATUS],
       Grp,
       CASE WHEN COUNT(ID) OVER (PARTITION BY CUSTOMER_NO, [STATUS], Grp) = 1 THEN 0
            ELSE ROW_NUMBER() OVER (PARTITION BY CUSTOMER_NO, [STATUS], Grp ORDER BY ID) - 1
       END AS [COUNTER]
FROM Grps;


0 commentaires

0
votes

Vous pouvez créer une numérotation comme un numéro de série pour le but de commande à l'aide de la fonction Row_Number () comme indiqué ci-dessous. XXX

Live DB <> FIDDLE démo.


3 commentaires

Je ne fais vraiment pas confiance à ce Row_Number () via (commander par (Sélectionnez NULL)) comme rn . Il ne fait aucune garantie que cela suivra l'ordre que le PO nous donne et pourrait donc facilement donner les mauvais résultats.


@Larnu qui est vrai, mais vous devez finalement utiliser quelque chose si une valeur n'est pas définie par OP pour la commande comme Numéro de client , Statut ou le compteur .


Oui, et si l'OP n'a pas de quelque chose à commander, alors tout simplement, ils ne peuvent pas atteindre ce qu'ils veulent; pas de manière fiable de toute façon. Cela pourrait facilement renvoyer un résultat différent chaque fois qu'il est exécuté.