【问题标题】:Using SQL JOIN and COUNT使用 SQL JOIN 和 COUNT
【发布时间】:2013-05-29 18:29:14
【问题描述】:

假设有两张表,一张保存用户信息,一张保存某种用户记录,比如收据。用户和收据之间是一对多的关系。

检索用户的最佳 SQL 方法是什么,按最大收据数排序?

我能想到的最好方法是使用 join 和 count(?) 返回一组用户及其相关收据的数量。

有没有办法在这种情况下使用计数功能?

select * from `users` inner join `receipts` on `users`.`id` = `receipts`.`uId`

【问题讨论】:

    标签: php mysql sql join


    【解决方案1】:

    如果 OP 希望使用来自users 表的数据包含其他信息(其他聚合等...):

    SELECT `users`.`id`,
           count(`receipts`.`uId`)
    FROM `users`
    INNER JOIN `receipts` ON `users`.`id` = `receipts`.`uId`
    GROUP BY `users`.`id`
    ORDER BY count(`receipts`.`uId`) DESC
    

    否则,只需要receipts 表...

    SELECT `users`.`id`,
           count(`receipts`.`uId`)
    FROM `receipts`
    GROUP BY `receipts`.`uId`
    ORDER BY count(`receipts`.`uId`) DESC
    

    【讨论】:

    • 。 .如果您打算将返回限制为仅 id,则无需加入。
    • 。 .这个查询仍然是错误的,除非它们恰好是receipts 表中名为receipts 的列。
    【解决方案2】:

    Dave 和 meewoK 提供的两个答案将满足您的需求。我提供了一种替代方法,应该提供更好的性能并允许您显示更多用户信息,因为在 Dave 的回答中,您只能选择聚合函数或组中使用的列子句。

    SELECT users.id, users.name, r.numReceipts  
    FROM users u
    INNER JOIN (
       SELECT uId, count(receipts) as numReceipts
       FROM receipts
       GROUP BY receipts.id
    ) as r ON r.uId = u.id
    ORDER BY r.numReceipts DESC
    

    这将创建一个内联视图。仅返回每个用户的收据计数,然后加入该用户 ID 的内联视图。

    如果我错了,有人会纠正我,但有人告诉我,当您在 SELECT 子句中执行标量子查询时,规划器效率不高。最好以这种方式加入临时表。有多种方法可以编写此查询,这完全取决于您要如何使用这些信息!!!干杯!

    【讨论】:

    • tbh 我不知道哪个更快我怀疑我这样做的方式要慢得多(当然在较大的表上),因为您执行全表 b 扫描并计算表 a 中的每个 uid。我的回答还取决于他不想要收据表中的任何数据,而你的表给了他这样的数据:) 尽管连接中的子选择可能也不是最好的方法。如果我想要一个计数器并检索两个表的详细信息,我会很想进行外部左连接。或者也许是一个工会,只选择整个地段:)
    • 是的,我绝对同意左连接是处理此任务的最有效方式。
    【解决方案3】:

    试试这个

    SELECT a.`id`, count(b.`recipts`) as total_receipts
    FROM `users` a
    INNER JOIN `receipts` b
    ON a.`id` = b.`uId`
    GROUP BY a.`id` 
    ORDER BY count(b.`receipts`) desc
    

    【讨论】:

      【解决方案4】:

      SELECT users.*, (SELECT COUNT(*) FROM tblreceipts WHERE tblreciepts.uId=users.id) as counter FROMusersORDER BY counter DESC

      这样的东西可能会起作用(虽然它的大桌子不确定速度)

      【讨论】:

        【解决方案5】:

        如果您想包含所有用户,即使是没有收据的用户,那么left outer join 是一个好方法:

        SELECT u.*, count(r.uid) as NumReceipts
        FROM `users` u left outer join
             `receipts` r
            ON u.id = r.`uId
        GROUP BY `u.id
        ORDER BY NumReceipts DESC;
        

        如果你只想要有收据的用户的 id,那么加入就没有必要了:

        SELECT r.uid, count(*) as NumReceipts
        FROM receipts r
        GROUP BY r.uid
        ORDER BY NumReceipts
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-11-12
          • 2021-04-01
          • 2021-10-21
          • 1970-01-01
          • 2012-10-24
          • 2018-07-09
          相关资源
          最近更新 更多