2009-04-27 5 views
5

J'essaie d'obtenir le nom d'un produit et son nombre de ventes à partir de deux tables distinctes.ÉNONCÉ DE CAS DANS COUNT CLAUSE

Mes tableaux ressemblent à ceci:

BOOK 
Book_ID | Book_Title | Book_Author 

SOLD 
Transaction_ID | Book_ID | Customer_ID 

Je peux obtenir la plupart des résultats que je veux de la requête suivante

SELECT b.Book_Title, COUNT(s.Book_ID) FROM Book b, Sold s 
WHERE b.Book_ID = s.Book_ID 
GROUP BY b.Book_Title; 

Cependant, cela ne affiche des produits avec au moins une vente. Je voudrais afficher tous les produits, montrant simplement un zéro si aucune vente n'a eu lieu. J'ai été déconner avec quelque chose comme ceci:

SELECT b.Book_Title, 
     COUNT(CASE WHEN s.Book_ID IS NULL THEN 0 ELSE s.Book_ID END) 
FROM Book b, Sold s WHERE b.Book_ID = s.Book_ID GROUP BY Book_Title; 

Mais la clause WHERE limite les résultats à ceux avec 1 ou plus de ventes.

Quelqu'un peut-il suggérer un moyen de contourner ce problème? J'utilise Oracle 10g.

Merci

Répondre

9

utiliser une jointure externe gauche:

SELECT b.Book_Title, COUNT(s.Book_ID) 
FROM Book b left outer join Sold s on b.Book_ID = s.Book_ID 
GROUP BY b.Book_Title; 
+0

Merci, cela a fait le travail :) –

+0

Notez que COUNT() compte réellement le nombre de valeurs non nulles, ce qui explique pourquoi cela fonctionne. –

-1

faire une autre jointure du livre vendu. vous pouvez toujours obtenir une valeur nulle pour le nombre, mais vous résolvez cela en ajoutant une NVL en plus de cela ...

0

Comme @Vincent a dit, vous avez besoin d'une jointure externe. Je n'ai pas beaucoup travaillé avec Oracle ces derniers temps, mais sa syntaxe de jointure externe propriétaire est plutôt bizarre. (Je ne sais pas s'ils ont pris à la norme ANSI sur ce point.)

La syntaxe est propriétaire:

SELECT b.Book_Title, 
     COUNT(s.Book_ID) 
    FROM Book b, 
     Sold s 
    WHERE b.Book_ID = s.Book_ID (+) 
GROUP BY b.Book_Title; 
0

Vous devriez obtenir le nombre dans une sous-requête et jointure externe gauche à elle en tant que telle :

select b.book_title, 
    case when s.book_id is null then 0 
     else s.salesCount end as Sales 
from book b 
left outer join 
    (select count(*) as salesCount, book_id from sales group by book_id) s on b.book_id = s.book_id 
1

Vous pouvez également utiliser une sous-requête corrélative dans la clause select:

select b.book_title, (select count(*) from sold s where s.book_id=b.book_id) from book b 

Il n'a pas besoin de group by ou de outer join, ce qui peut être lent pour un très grand nombre de lignes.