2013-06-27 2 views
0

J'ai un schéma comme:Comment puis-je obtenir plusieurs comptes d'une colonne dans une requête SQL?

PetOwner: 
owner_id | first_name | last_name 
--------------------------------- 
1  | john  | smith 
2  | jane  | doe 
3  | jack  | jones  

Pets: 
pet_id | owner_id | name | type 
------------------------------- 
1  | 1  | a | dog 
2  | 1  | b | dog 
3  | 1  | c | dog 
4  | 1  | d | cat 
5  | 1  | e | cat 
6  | 1  | f | fish 
7  | 2  | g | dog 
8  | 2  | h | dog 
9  | 2  | i | fish 
10  | 3  | j | dog 

Je voudrais écrire une requête qui me donne:

first_name | last_name | dog_count | cat_count | fish_count 
----------------------------------------------------------- 
john  | smith  | 3   | 2   | 1 
jane  | doe  | 2   | 0   | 1 
jack  | jones  | 1   | 0   | 0 

Il y a un ensemble connu de types d'animaux, donc cela n'a pas besoin faire une colonne pour les types arbitraires. En outre, les propriétaires qui n'ont pas un certain type d'animal de compagnie devraient avoir un compte de 0 pour ce type d'animal de compagnie.

J'ai déjà essayé une requête comme:

SELECT first_name, last_name, owner_id, type, COUNT(*) 
FROM Pets, PetsOwner 
GROUP_BY owner_id, type 

qui donne:

first_name | last_name | owner_id | type | COUNT(*) 
--------------------------------------------------- 
john  | smith  | 1  | dog | 3 
john  | smith  | 1  | cat | 2 
john  | smith  | 1  | fish | 1 
jane  | doe  | 2  | dog | 2 
jane  | doe  | 2  | fish | 1 
jack  | jones  | 3  | dog | 1 

Mais cette itérer demande sur l'ensemble des résultats pour obtenir la sortie que je cherche, de toute évidence quelque chose éviter avec SQL. En outre, il ne fournit pas la valeur 0 par défaut pour les types d'animaux de compagnie absents de la table.

Est-il possible de le faire avec une requête SQL? Si non, y a-t-il une requête que je pourrais faire qui soit meilleure (c'est-à-dire plus facile à utiliser) que la requête que j'ai trouvée?

Il est une base de données MySQL, si cela fait une différence.

Merci pour l'aide.

Répondre

2

Utilisez SUM au lieu de COUNT:

SELECT o.first_name, o.last_name, 
     SUM(CASE WHEN p.type = 'cat' THEN 1 ELSE 0 END) as cat_count, 
     SUM(CASE WHEN p.type = 'dog' THEN 1 ELSE 0 END) as dog_count, 
     SUM(CASE WHEN p.type = 'fish' THEN 1 ELSE 0 END) as fish_count 
FROM PetOwners o 
JOIN Pets p ON o.id = p.owner_id 
GROUP BY o.id 

Et si vous voulez inclure les propriétaires qui n'ont pas des animaux de compagnie du tout, le changement JOIN-LEFT JOIN.

Questions connexes