Savoir quand les valeurs additionnées ont atteint un certain sharepoint contrôle dans SQL

Tout d'abord: j'ai trouvé quelques réponses possibles à mon problème dans les questions précédemment posées, mais j'ai rencontré des problèmes pour les faire fonctionner correctement. Je sais que la question a déjà été posée, mais les réponses ont toujours été un code de travail avec peu ou pas d'explication sur la méthode utilisée.

Donc: Je dois savoir quand un client a atteint le statut VIP, quand la valeur de ses commands dépasse 50 000. J'ai 2 tables: une avec orderid, customerid et orderdate, et la seconde avec orderid, quantité et prix unitaire. Le résultat de la requête que j'écris devrait être de 3 colonnes de large, une avec le client, une avec le vrai / faux nommé "est VIP?", Et la troisième est la date d'obtention du statut VIP (qui est la date de la command celle additionnée aux précédentes donne un résultat de plus de 50 000) – la dernière devrait être vide si le client n'a pas atteint le statut VIP

select o.customerid, sum(od.quantity*od.unitprice), case when sum(od.quantity*od.unitprice)>50000 then 'VIP' else 'Normal' end as 'if vip' from orders o join [Order Details] od on od.orderid=o.orderid group by o.customerid 

C'est aussi loin que je l'ai eu avec le code, il returnne le statut du client et maintenant j'ai besoin d'get la date à laquelle cela s'est produit. .

Vous pouvez facilement calculer un total cumulé en utilisant une fonction de window:

 select o.customerid, o.orderdate, sum(od.quantity*od.unitprice) over (partition by o.customerid order by orderdate) as running_sum, from orders o join Order_Details od on od.orderid = o.orderid order by customer_id, orderdate; 

Vous devez maintenant find un moyen de détecter la première ligne, où le total cumulé dépasse le seuil:

La requête suivante commence à numéroter les lignes de manière descendante une fois le seuil atteint. Ce qui à son tour signifie que la ligne avec le numéro 1 est la première à franchir le seuil:

 with totals as ( select o.customerid, o.orderdate, sum(od.quantity*od.unitprice) over (partition by o.customerid order by orderdate) as running_sum, case when sum(od.quantity*od.unitprice) over (partition by o.customerid order by orderdate) > 50000 then row_number() over (partition by o.customerid order by orderdate desc) else 0 end as rn from orders o join Order_Details od on od.orderid = o.orderid ) select * from totals where rn = 1 order by customerid; 

Exemple SQLFiddle: http://sqlfiddle.com/#!6/a7f18/3

Vous obtenez la sum cumulée en utilisant une fonction analytique, SUM OVER . Et puis ajoutez un agrégat pour find la date minimum:

 with cte as ( select o.customerid, o.orderdate, case when sum(od.quantity*od.unitprice) -- running total over (partition by o.customerid order by orderdate rows unbounded preceding) > 50000 then 'Y' else 'N' end as VIP from orders o join Order_Details od on od.orderid = o.orderid ) select customerid, MAX(VIP) AS "isVIP?", -- either 'N' or 'Y' MIN(CASE WHEN VIP = 'Y' THEN orderdate END) AS VIP_date -- only when VIP status reached from cte group by customerid order by customers; 

Voir violon

Ne va pas compliquer la réponse avec logique pour montrer «vip» et «vip date». Cela vous donnera un total cumulé pour chaque command client.

select o.orderid, o.customerid, o.orderdate, sum(od.quantity*od.unitprice) 'Total', ( select sum(od.quantity * od.unitprice) total from orders o2 join [Order Details] od2 on od2.orderid=o2.orderid where o2.orderID <= o.orderID and o2.customerid = o.customerid) 'RunningTotal' from orders o join [Order Details] od on od.orderid=o.orderid group by o.orderid, o.customerid, o.orderdate order by o.customerid

Pour répondre à votre question sur la façon d'approcher, vous pouvez envisager d'utiliser un triggersur SQL qui s'exécute à chaque mise à jour des tables impliquées et définit le statut lorsque le seuil est atteint. Cela définira la date au moment et au moment de l'événement.

Une autre approche consisterait à utiliser une procédure stockée dans laquelle vous pouvez utiliser un sumt de boucle parcourir les loggings et arriver à la date.

Le choix peut être fait sur la base du volume des données, avec le premier apport approprié pour des quantités extrêmement importantes de données.