如何计算表中每个外键ID的实例数?

时间:2011-09-15 01:28:18

标签: mysql sql

这是我简单的SQL问题......

我有两张桌子:

图书

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

订单

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

我想创建一个返回:

的查询
--------------------------------------------------------------------------
| book_id | author | genre | price | publication_date | number_of_orders |
--------------------------------------------------------------------------

换句话说,返回Books表中 ALL 行的每一列,以及一个名为“number_of_orders”的计算列,该列计算每本书在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

几乎正确,但并不完全,因为即使书籍从未在Orders表中列出,“number_of_orders”也将为1。此外,由于我缺乏SQL知识,我确信这个查询效率非常低。

编写此查询的正确方法是什么? (对于它的价值,这需要适用于MySQL,因此我不能使用任何其他特定于供应商的功能。)

提前致谢!

5 个答案:

答案 0 :(得分:89)

您的查询几乎是正确的,这是正确的方法(并且效率最高)

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值。

答案 1 :(得分:5)

count(*)更改为count(orders.book_id)

答案 2 :(得分: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)

答案 3 :(得分:1)

你算错了。您想要计算非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 :(得分:1)

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;