2009-04-27 15 views
5

Sto cercando di ottenere il nome di un prodotto e il suo numero di vendite da due tabelle separate.SQL CASE STATEMENT in COUNT CLAUSE

mie tabelle di qualcosa di simile a questo:

BOOK 
Book_ID | Book_Title | Book_Author 

SOLD 
Transaction_ID | Book_ID | Customer_ID 

posso ottenere la maggior parte dei risultati che voglio dalla seguente query

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; 

Tuttavia, questo solo mostra i prodotti con almeno una vendita. Vorrei visualizzare tutti i prodotti, mostrando semplicemente zero se non si sono verificate vendite. Sono stato nei guai con qualcosa di simile:

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; 

Ma la clausola WHERE sta limitando i risultati a quelli con 1 o più vendite.

Qualcuno può suggerire un modo per aggirare questo? Sto usando Oracle 10g.

Grazie

risposta

9

utilizzare un join esterno sinistro:

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

Grazie, ha fatto il lavoro :) –

+0

Nota che COUNT() sta effettivamente contando il numero di valori non nulli, motivo per cui funziona. –

-1

fa un altro join dal libro al venduto. si può ancora ottenere un nullo per il conteggio, ma risolvere che con l'aggiunta di un NVL in cima a quello ...

0

Come ha detto @Vincent, è necessario un outer join. Ultimamente non ho lavorato molto con Oracle, ma la sua sintassi proprietaria di outer join è piuttosto bizzarra. (Non so se hanno raggiunto con ANSI su quello.)

La sintassi proprietaria è:

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

si dovrebbe ottenere il conteggio in una sottoquery e lasciato outer join ad esso come tale :

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

È inoltre possibile utilizzare una subquery correlata nella clausola select:

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

Non è necessario né group byouter join s, che può essere lento per un numero molto elevato di righe.