Как посчитать количество экземпляров каждого идентификатора внешнего ключа в таблице? - PullRequest
49 голосов
/ 15 сентября 2011

Вот мой простой вопрос SQL ...

У меня есть две таблицы:

Книги

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

Заказы

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

I 'Я хотел бы создать запрос, который возвращает:

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

Другими словами, возвращайте каждый столбец для ALL строк в таблице Books вместе с вычисляемым столбцом с именем 'number_of_orders', который считаетколичество раз, когда каждая книга появляется в таблице заказов.(Если книга отсутствует в таблице заказов, книга должна быть должна быть указана в наборе результатов, но "number_of_orders" должно быть ноль .

Пока чтоЯ придумал это:

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

Это почти верно, но не совсем, потому что "number_of_orders" будет равно 1, даже если книга никогда не указана в таблице "Заказы"Более того, учитывая мое незнание SQL, я уверен, что этот запрос очень неэффективен.

Как правильно написать этот запрос? (Для чего это нужно, он должен работать на MySQL, поэтомуЯ не могу использовать другие функции, специфичные для поставщика).

Заранее спасибо!

Ответы [ 5 ]

90 голосов
/ 15 сентября 2011

Ваш запрос почти правильный, и это правильный способ сделать это (и самый эффективный)

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(*) может включать значения NULL в счетчик, потому что он подсчитывает все строки, в то время как COUNT(orders.book_id) нет, потому что игнорирует значения NULL в данном поле.

5 голосов
/ 15 сентября 2011

Изменить count(*) на count(orders.book_id)

4 голосов
/ 15 сентября 2011
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)
1 голос
/ 02 апреля 2018
select author.aname,count(book.author_id) as "number_of_books"
from author 
left join book 
on(author.author_id=book.author_id)
GROUP BY author.aname;
1 голос
/ 15 сентября 2011

Вы считаете неправильную вещь. Вы хотите посчитать ненулевые значения 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...