2010-12-13 35 views
1

J'ai une table à la clientèle et une table OrderDetail l'identifiant du client est une clé foriegn dans la table OrderDetail (je simplifie)Aide avec SQL - GroupBy et plusieurs agrégats

La table OrderDetail contient les colonnes suivantes OrderId ItemId CustomerId Taille

La colonne Taille peut prendre l'une des valeurs suivantes 1. lr 2. 3. md sm

Ainsi, la table OrderDetail pourrait avoir les documents suivants (je l'ai séparés par des virgules les colonnes)

OrderId ItemId CustomerId Taille

1,1,30,lr 
1,1,30,md 
1,1,30,sm 
2,1,30,lr 
2,1,30,md 
3,1,30,lr 
3,1,30,sm 
4,1,30,lr 
5,1,30,md 
6,2,30,sm 
7,3,30,md 
8,3,30,lr 

Ce que je voudrais est une question très efficace (il y a des millions d'enregistrements dans les détails de la commande tables) qui a la sortie suivante pour une donnée customerId (30 dans ce cas)

ItemId SizeLr SizeMd SizeSm 
1   4  3  2 
2   0  0  1 
3   1  1  0 

la requête J'utilise utilise 3 groupe par des requêtes (un pour chaque « lr », « MD » et "sm") et en conséquence il scanne la table 3 fois.

Je suis à la recherche d'une solution qui scanne la table juste onces. Je pense que la solution utilise la nouvelle fonction Grouping Set dans MSSQL 2008. Mais dans les deux cas, une solution utilisant un scan est ce que j'espère que quelqu'un pourra m'aider.

EDIT

La production réelle a besoin d'avoir d'autres champs de la table des clients et la table des détails de la commande ainsi. Ces autres champs ne dépendent pas des agrégats.

Par exemple

ItemName ItemId SizeLr SizeMd SizeSm 
    A   1  4  3  2 
    B   2  0  0  1 
    C   3  1  1  0 
    Totals   5  4  4 

Il serait bien si je pouvais obtenir les totaux pour chacune des colonnes de taille et

+0

sont les autres colonnes du tableau des détails de la commande en fonction de la taille. Si ce n'est pas le cas, spezify comment les afficher. –

+0

J'ai mis à jour la question pour inclure cette information. Désolé de ne pas être plus clair la première fois. –

Répondre

1

Que diriez-vous ceci:

SELECT ItemId, 
    SUM(CASE WHEN Size = 'Lr' THEN 1 ELSE 0 END) AS SizeLr, 
    SUM(CASE WHEN Size = 'Md' THEN 1 ELSE 0 END) AS SizeMd, 
    SUM(CASE WHEN Size = 'Sm' THEN 1 ELSE 0 END) AS SizeSm 
FROM OrderDetail 
WHERE CustomerId = 30 
GROUP BY ItemId 
+0

J'aurais dû mentionner dans le message original que j'ai besoin d'autres champs de la table client et orderdetails qui ne sont pas des agrégats. Alors, comment pourrais-je inclure ces champs aussi? –

+0

Oui, et vous devriez également ajouter quelle est la sortie réelle dont vous avez besoin, afin que les gens puissent vous donner une réponse – Lamak

+0

Je vais marquer cela comme la réponse car elle répond à la question telle qu'elle a été énoncée initialement. –

1

Essayez ceci:

select Itemid, 
    sum (case when Size = 'lr' then 1 else 0 end) SizeLR, 
    sum (case when Size = 'Md' then 1 else 0 end) SizeMd, 
    sum (case when Size = 'SM' then 1 else 0 end) SizeSM 
from orderdetail 
group by Itemid 
order by Itemid;  

Si je temName dépend de ItemId vous pouvez le faire:

select Itemname, Itemid, 
    sum (case when Size = 'lr' then 1 else 0 end) SizeLR, 
    sum (case when Size = 'Md' then 1 else 0 end) SizeMd, 
    sum (case when Size = 'SM' then 1 else 0 end) SizeSM 
from orderdetail 
group by Itemid, Itemname 
order by Itemid;