【问题标题】:SQL question about counting关于计数的SQL问题
【发布时间】:2009-08-24 11:27:32
【问题描述】:

我想进行查询,以便只能获取至少有 50 个地点的位置。

我有一张位置表:

Id, City, Country
1, Austin, USA
2, Paris, France

还有一个按 Location_id 连接到 Locations 的 Places 表

Id, Name, Details, Location_id
1, The Zoo, blah, 2
2, Big Park, blah, 2

我可以像这样加入他们:

选择places.name、places.id、locations.country、locations.city 从地方 INNER JOIN 位置 ON places.location_id = locations.id

如何才能仅获得至少有 50 个地点的城市的结果并按最大数量排序?

谢谢!

【问题讨论】:

    标签: sql mysql ruby-on-rails count aggregate


    【解决方案1】:

    使用GROUP BY with a HAVING 子句。

    SELECT locations.country, locations.city, COUNT(*)
    FROM places
         INNER JOIN locations ON places.location_id = locations.id
    GROUP BY locations.country, locations.city
    HAVING COUNT(*) >= 50
    

    【讨论】:

    • 只是缺少 ... COUNT(*) as count_of_places ... ORDER BY count_of_places DESC
    • 问题是,在按地点分组后,您将无法获得按位置分组的正确count(*)
    • 不确定这是否有效:您按places.id 分组,但是(假设places 中的Id 列是唯一键)这意味着所有组都有一个成员。
    • 我不知道为什么人们会支持你。您的查询将返回 0 行,因为您是 count(*) 将始终返回 1。
    • 哎呀,没有注意到这是错误的,它应该只按位置而不是按地点分组!
    【解决方案2】:

    好的,我已经看到上面的答案差不多了,但有一些错误,所以发布正确的版本:

    SELECT locations.country, locations.city, COUNT(*) as count_of_places
    FROM places
         INNER JOIN locations ON places.location_id = locations.id
    GROUP BY locations.country, locations.city
    HAVING COUNT(*) >= 50
    ORDER BY count_of_places;
    

    【讨论】:

    • +1 如果不是唯一一个真正有工作查询的人.
    • 实际上,订单从最低金额开始。应该是DESC吗?
    【解决方案3】:

    您可以使用having 子句通过聚合列的值来限制这些行。此外,MySQL 允许您使用惰性group bys,因此您绝对可以利用这一点:

    select
        l.country,
        l.city,
        p.name,
        p.details,
        count(*) as number_of_places
    from
        locations l
        inner join places p on
            l.id = p.location_id
    group by
        l.id
    having
        count(*) >= 50
    order by
        number_of_places,
        l.country,
        l.city,
        p.name
    

    【讨论】:

    • 这不会编译 - SELECT 中聚合函数之外的任何内容都需要在 GROUP BY 中。
    • @andrew:不在 MySQL 中。在 SQL Server 中,它确实如此。这就是我所说的 MySQL 的“懒惰group bys”。太棒了,嗯?
    【解决方案4】:

    表现不佳,但应该可以:

    SELECT places.name, places.id, sq.country, sq.city, sq.counter FROM (SELECT Locations.id, country,city, count(*) as counter FROM Locations JOIN Places ON (Locations.Id=Places.Location_id) GROUP BY locations.id HAVING count(*) >= 50) AS sq JOIN Places ON (sq.id=Places.Location_id) ORDER BY counter DESC`

    附:确切的语法可能因数据库而异,我不确定这是否与mysql-兼容。

    【讨论】:

      猜你喜欢
      • 2021-07-03
      • 2022-11-16
      • 1970-01-01
      • 2021-11-25
      • 2011-10-26
      • 1970-01-01
      • 1970-01-01
      • 2013-05-14
      相关资源
      最近更新 更多