2011-09-15 17 views
39

Oto mój prosty SQL pytanie ...Jak policzyć liczbę wystąpień każdego identyfikatora klucza obcego w tabeli?

Mam dwie tabele:

Książki

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

Zamówienia

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

Chciałbym utworzyć kwerendę zwracającą:

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

Innymi słowy, zwracaj każdą kolumnę dla wierszy w tabeli Książki wraz z kolumną obliczeniową o nazwie "liczba_zakupów", która zlicza ile razy każda książka pojawia się w tabeli Zamówienia. . (Jeśli książka nie występuje w tabeli zamówień, książka powinny być wymienione w tabeli wynikowej, ale „number_of_orders” należy zerowy

tej pory, mam wymyślić to:

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 

to prawie rację, ale nie do końca, bo „number_of_orders” będzie 1 nawet jeśli książka nie jest wymieniony w tabeli Zamówienia. Ponadto, biorąc pod uwagę mój brak znajomości SQL, jestem pewien, że ten zapytanie jest bardzo nieefektywne.

Jaki jest właściwy sposób napisania tego zapytania? (Co jest warte, to musi działać na MySQL, więc nie mogę używać żadnych innych funkcji specyficznych dla danego dostawcy).

Z góry dziękuję!

Odpowiedz

62

Zapytanie jest prawie w porządku i jest to dobry sposób, żeby to zrobić (i najbardziej efektywny)

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(*) może zawierać wartości NULL w liczbie, ponieważ liczy się wszystko wiersze, podczas gdy COUNT(orders.book_id) nie robi, ponieważ ignoruje wartości NULL w danym polu.

+2

Twoje ostatnie stwierdzenie może być nieco mylące. Funkcja COUNT sama ignoruje wartości NULL, gdy agreguje dane. Powodem, dla którego COUNT (*) zwraca nieprawidłowe liczby, jest liczba wierszy zamiast konkretnej kolumny. Po prostu chcę wyjaśnić OP –

+0

Zaktualizowano odpowiedź, thx. – Fabio

+0

@Fabio jakie jest to wywołanie tego konkretnego zapytania, dla zliczania powiązanych wpisów w innej tabeli? Czy ma jakieś akademickie imię? –

5

Zmień count(*) do count(orders.book_id)

1

Liczysz złą rzecz. Chcesz policzyć nie puste wartości 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) 
Powiązane problemy