108 votes

SQL somme avec condition

Actuellement, j'ai une longue déclaration SQL à laquelle j'ajoute la ligne suivante afin d'obtenir le total des espèces pour chaque identifiant de transaction (qui sont uniques) :

select sum(cash) from Table a where a.branch = p.branch 
et a.transID = p.transID) TotalCash

et maintenant j'ai besoin de faire la même chose mais seulement totaliser les valeurs en espèces qui ont une date de valeur dans le mois dernier, donc j'ai quelque chose comme ceci :

select sum(CASE ValueDate WHEN > @startMonthDate THEN cash ELSE NULL END) 
from Table a where a.branch = p.branch et a.transID = p.transID) TotalMonthCash

Désolé, je n'ai pas la déclaration complète, mais elle est vraiment longue et spécifique au contexte de la procédure stockée, mais j'espérais que quelqu'un saurait ce que je veux dire?

199voto

Mark Byers Points 318575

Essayez ceci à la place :

SUM(CASE WHEN ValueDate > @startMonthDate THEN cash ELSE 0 END)

Explication

Votre expression CASE a une syntaxe incorrecte. Il semble que vous confondiez la syntaxe de l'expression CASE simple avec la syntaxe de l'expression CASE recherchée. Consultez la documentation pour CASE :

L'expression CASE a deux formats :

  • L'expression CASE simple compare une expression à un ensemble d'expressions simples pour déterminer le résultat.
  • L'expression CASE recherchée évalue un ensemble d'expressions booléennes pour déterminer le résultat.

Vous voulez la syntaxe de l'expression CASE recherchée :

CASE
     WHEN expression_booléenne THEN expression_résultat [ ...n ] 
     [ ELSE expression_autre_résultat ] 
END

En passant, si la performance pose problème, vous pourriez constater que cette expression s'exécute plus rapidement si vous la reécrivez en utilisant un JOIN et GROUP BY au lieu d'utiliser une sous-requête dépendante.

9voto

James Wiseman Points 18347

Essayez de déplacer ValueDate:

select sum(CASE  
             WHEN ValueDate > @startMonthDate THEN cash 
              ELSE 0 
           END) 
 from Table a
where a.branch = p.branch 
  and a.transID = p.transID

(reformaté pour plus de clarté)

Vous pourriez également envisager d'utiliser '0' au lieu de NULL, car vous faites une somme. Les deux façons fonctionnent correctement, mais la première est peut-être plus indicative de vos intentions.

1voto

Avec la condition HAVING, vous éliminerez les données avec de l'argent ne dépassant pas 0 si vous le souhaitez, ce qui générera plus d'efficacité dans votre requête.

SELECT SUM(cash) AS money FROM Table t1, Table2 t2 WHERE t1.branch = t2.branch 
AND t1.transID = t2.transID
AND ValueDate > @startMonthDate HAVING money > 0;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X