4 votes

Obtenez la somme d'une colonne regroupée par une autre colonne puis regroupée dans une autre

J'ai essayé depuis un certain temps de comprendre cela, mais mon manque de compétences avancées en SQL me retient.

Executions(TradeDate, Symbol, Side, Price, Under, Account)

DONNÉES TEMPORAIRE :
2012-06-20, AAPL 120716C00600000, ACHETER, 3.25, AAPL, XYZ123
2012-06-20, AAPL 120716C00600000, VENDRE, 3.30, AAPL, XYZ123
2012-06-20, AAPL 120716C00600000, ACHETER, 3.25, AAPL, XYZ123
2012-06-20, AAPL 120716C00600000, VENDRE, 3.30, AAPL, XYZ123
2012-06-20, GRPN 120716C00027000, ACHETER, 2.25, GRPN, XYZ123
2012-06-20, GRPN 120716C00027000, VENDRE, 2.30, GRPN, XYZ123
2012-06-20, GRPN 120716C00027000, VENDRE, 2.30, GRPN, XYZ123
2012-06-20, GRPN 120716C00027000, ACHETER, 2.25, GRPN, XYZ123

-SOUS----Côté(Acheter)----Côté(Vendre)
 AAPL      6.50         6.60
 GRPN      4.50         4.60

Comme vous pouvez le voir, j'essaie d'obtenir la SOMME du prix pour chaque côté et ensuite regroupé par le Sous-jacent.

6voto

aF. Points 15815

Utilisez GROUP BY pour regrouper par colonne Under et CASE associé à SUM pour obtenir les résultats nécessaires :

SELECT e.Under,
       SUM(case when e.Side = 'BUY' them e.Price else 0 end) as 'Achat',
       SUM(case when e.Side = 'SELL' them e.Price else 0 end) as 'Vente'
FROM Executions e
GROUP BY e.Under

3voto

bluefeet Points 105508

Vous pouvez utiliser un PIVOT pour cela. (Voir SQL Fiddle pour la démo)

select *
from 
(
    select under, price, side
    from executions
) x
PIVOT
(
    sum(price)
    for side in ([ACHETER], [VENDRE])
) p

0voto

spencer7593 Points 29263

Voici une approche :

SELECT e.under
     , SUM(CASE WHEN e.side = 'BUY'  THEN e.price ELSE NULL END) AS [Côté(Achat)]
     , SUM(CASE WHEN e.side = 'SELL' THEN e.price ELSE NULL END) AS [Côté(Vente)]
  FROM Executions e
 GROUP BY e.under

Le "tour de passe-passe" ici est d'utiliser une expression CASE pour retourner le Prix uniquement pour certaines valeurs de côté. (REMARQUE : Comme quelqu'un le soulignera inévitablement, le ELSE NULL est implicite et peut être omis.)

Ce n'est pas la seule approche. Mais c'est une approche flexible qui fonctionne très bien si vous avez également besoin, par exemple, d'un "count" des lignes incluses dans chacune des sommes, ainsi qu'un count de toutes les lignes. Pour illustrer cette approche en action :

 SELECT e.under
     , SUM(CASE WHEN e.side = 'BUY'  THEN e.price ELSE NULL END) AS [SUM_Côté(Achat)]
     , SUM(CASE WHEN e.side = 'BUY'  THEN 1       ELSE 0    END) AS [COUNT_Côté(Achat)]
     , SUM(CASE WHEN e.side = 'SELL' THEN e.price ELSE NULL END) AS [SUM_Côté(Vente)]
     , SUM(CASE WHEN e.side = 'SELL' THEN 1       ELSE 0    END) AS [COUNT_Côté(Vente)]
     , SUM(CASE WHEN e.side IN ('BUY','SELL') THEN 1 ELSE 0 END) AS [COUNT_(Achat+Vente)]
  FROM Executions e
 GROUP BY e.under

Cette approche a généralement des performances très prévisibles et elle nécessite que l'ensemble de données source ne soit référencé qu'une seule fois (dans ce cas, une simple référence de table)

Cette approche fonctionne dans presque tous les bases de données relationnelles. (Oracle, SQL Server, MySQL, Teradata, DB2, ...)

0voto

Sean Points 1468
select Symbol, sum(case when side = 'ACHETER' THEN Price else 0 END) as [Côté(Acheter)], sum(case when side = 'VENDRE' THEN Price else 0 END) as [Côté(Vendre)] group by Symbol

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