2009-01-09 7 views
1

J'ai ces tables:groupe par défi de requête

customer 
-------- 
customer_id int 
name  varchar(255) 

order 
----- 
order_id int 
customer_id int 
discount boolean 

Je peux obtenir le nombre de commandes effectuées par chaque client avec une requête comme:

select c.id, count(o.order_id) 
from customer c 
left join order as o using c.customer_id = o.customer_id 
group by 1 

Sinon, je peux obtenir le nombre de commandes actualisées faites par chaque client avec:

select c.id, count(o.order_id) 
from customer c 
left join order as o using c.customer_id = o.customer_id and o.discount = true 
group by 1 

Mais je ne peux pas trouver un moyen d'obtenir les deux dans une seule requête. J'ai essayé ce qui suit:

select c.id, count(o.order_id), count(o2.order_id) 
from customer c 
left join order as o using c.customer_id = o.customer_id 
left join order as o2 using c.customer_id = o2.customer_id and o2.discount = true 
group by 1 

Mais cela n'a pas fonctionné. Est-il possible de calculer les deux en une seule requête (MySql)?

Cheers, Don

Répondre

3

Que diriez-vous quelque chose comme

select c.id, count(o.order_id),sum(if(o.discount,1,0)) 
from customer c 
left join order as o using c.customer_id = o.customer_id 
group by c.id 
+0

Dans les systèmes qui ne sont pas la fonction SI, une expression CASE dolby La fonction peut être utilisée à la place. –

+0

Vous avez raison, CASE est plus standard SQL, mais l'OP dit qu'il utilise MySQL, qui supporte la fonction IF(). –

1

Vous pouvez faire somethings comme

select 
c.id, 
sum(case o.discount when true then 1 else 0 end) as 'total discounted', 
count(o.order_id) as 'total orders' 
from customer as c 
left join order as o using c.customer_id = o.customer_id 
group by c.id 
1

D'autres réponses se rapprocher, mais voici comment je l'écris:

SELECT c.id, COUNT(o.order_id) AS order_count, 
    SUM(o.discount = true) AS discount_order_count 
FROM customer c 
    LEFT OUTER JOIN order AS o USING (customer_id) 
GROUP BY c.id; 

Notez que l'utilisation de USING requiert des parenthèses et n'accepte qu'une liste de colonnes qui seront comparées avec =. Vous ne pouvez pas donner une expression de comparaison complète avec la syntaxe USING comme vous pouvez avec la syntaxe ON.

vous pouvez également simplifier l'expression à l'intérieur SUM() car une comparaison d'égalité retourne 1 ou 0.

Voir aussi « Query: count multiple aggregates per item »