2011-09-15 3 views
39

Voici ma question simple SQL ...Comment compter le nombre d'instances de chaque ID de clé étrangère dans une table?

J'ai deux tables:

Livres

------------------------------------------------------- 
| book_id | author | genre | price | publication_date | 
------------------------------------------------------- 

Commandes

------------------------------------ 
| order_id | customer_id | book_id | 
------------------------------------ 

Je voudrais créer une requête qui retourne:

-------------------------------------------------------------------------- 
| book_id | author | genre | price | publication_date | number_of_orders | 
-------------------------------------------------------------------------- 

En d'autres termes, renvoyez chaque colonne pour ALL lignes dans la table Books, avec une colonne calculée nommée 'number_of_orders' qui compte le nombre de fois que chaque livre apparaît dans la table Orders. . (Si un livre ne se produit pas dans le tableau des commandes, le livre devrait être répertoriés dans le jeu de résultats, mais « number_of_orders » devrait être zéro

Jusqu'à présent, je suis venu avec ceci:

SELECT 
    books.book_id, 
    books.author, 
    books.genre, 
    books.price, 
    books.publication_date, 
    count(*) as number_of_orders 
from books 
left join orders 
on (books.book_id = orders.book_id) 
group by 
    books.book_id, 
    books.author, 
    books.genre, 
    books.price, 
    books.publication_date 

C'est presque droite, mais pas tout à fait, parce que « number_of_orders » sera 1 même si un livre est jamais répertorié dans le tableau des commandes. de plus, compte tenu de mon manque de connaissance de SQL, je suis sûr que ce la requête est très inefficace

Quelle est la bonne façon d'écrire cette requête? (Pour ce que ça vaut, cela doit fonctionner sur MySQL, donc je ne peux pas utiliser d'autres fonctionnalités spécifiques au fournisseur).

Merci d'avance!

Répondre

62

Votre requête est presque droit et il est la bonne façon de le faire (et le plus efficace)

SELECT books.*, count(orders.book_id) as number_of_orders   
from books 
left join orders 
on (books.book_id = orders.book_id) 
group by 
    books.book_id 

COUNT(*) pourrait inclure des valeurs NULL dans le compte, car il compte tous les lignes, tandis que COUNT(orders.book_id) non parce qu'il ignore les valeurs NULL dans le champ donné.

+2

Votre déclaration pourrait être quelque peu trompeur. La fonction COUNT elle-même ignore les valeurs NULL lors de l'agrégation des données. La raison pour laquelle COUNT (*) renvoie des comptes erronés est parce que ses lignes de comptage au lieu d'une colonne spécifique. Je veux juste clarifier pour l'OP –

+0

Mis à jour la réponse, thx. – Fabio

+0

@Fabio Quelle est cette requête particulière appelée, pour compter les entrées connexes dans l'autre table? Est-ce qu'il a un nom académique? –

5

changement count(*) à count(orders.book_id)

1

Vous comptez la mauvaise chose. Vous voulez compter le non-null book_id.

SELECT 
    books.book_id, 
    books.author, 
    books.genre, 
    books.price, 
    books.publication_date, 
    count(orders.book_id) as number_of_orders 
from books 
left join orders 
on (books.book_id = orders.book_id) 
group by 
    books.book_id, 
    books.author, 
    books.genre, 
    books.price, 
    books.publication_date 
4
SELECT b.book_id, 
    b.author, 
    b.genre, 
    b.price, 
    b.publication_date, 
    coalesce(oc.Count, 0) as number_of_orders 
from books b 
left join (
    select book_id, count(*) as Count 
    from Order 
    group by book_id 
) oc on (b.book_id = oc.book_id) 
Questions connexes