【问题标题】:How to count the number of instances of each foreign-key ID in a table?如何统计表中每个外键 ID 的实例数?
【发布时间】:2011-09-15 01:28:18
【问题描述】:

这是我的简单 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

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

编写此查询的正确方法是什么? (无论如何,这需要在 MySQL 上运行,所以我不能使用任何其他供应商特定的功能)。

提前致谢!

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    您的查询几乎是正确的,这是正确的方法(也是最有效的)

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

    【讨论】:

    • 您最后的陈述可能有些误导。 COUNT 函数本身在聚合数据时会忽略 NULL 值。 COUNT(*) 在这里返回错误计数的原因是因为它计数行而不是特定列。只是想为 OP 澄清一下
    • @Fabio 这个特定的查询叫什么,用于计算其他表中的相关条目?它有学术名称吗?
    • @KamalReddy AFAIK 这种查询在学术界没有任何特定名称。
    • @Fabio 谢谢。我不明白 join 如何与 () 语句一起使用。你能解释一下这方面的一些光或一些文献或例子吗?
    • PostgreSQL 要求我在 group 语句中包含我选择的每个字段。 ERROR: column "..." must appear in the GROUP BY clause or be used in an aggregate function 有什么解决方法的想法吗? (除了实际做它要求我做的事情)
    【解决方案2】:
    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】:

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

      【讨论】:

        【解决方案4】:

        你算错了。您要计算非空 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
        

        【讨论】:

          【解决方案5】:
          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;
          

          【讨论】:

            猜你喜欢
            • 2017-08-01
            • 2021-06-18
            • 2014-10-16
            • 1970-01-01
            • 1970-01-01
            • 2016-03-08
            • 1970-01-01
            • 2020-01-04
            • 1970-01-01
            相关资源
            最近更新 更多