【问题标题】:Writing Queries without the limit clause编写没有限制子句的查询
【发布时间】:2020-06-05 02:42:43
【问题描述】:

如何在没有 Limit 子句的情况下重写以下查询?

SELECT project.title, 
       COUNT(project2manager.managerid) AS Cnt_Manager
FROM project2manager 
JOIN project ON project2manager.projectid = project.projectid 
GROUP BY project.title
ORDER BY Count_Manager DESC LIMIT 1;

+-----------------+-------------+
| project.title   | Cnt_Manager |
+-----------------+-------------+
| City Scape      |           8 |
+-----------------+-------------+

我尝试使用 MAX 子句,但我一直得到不正确的项目标题,但经理人数却是正确的。解决此问题的最佳方法是什么?

SELECT title , MAX(Total) 
FROM (SELECT project.title, COUNT(project2manager.managerid) AS Total
FROM project2manager 
JOIN project ON project2manager.projectid = project.projectid 
GROUP BY project.title) AS Result;
+-------------------------+------------+
| project.title           | MAX(Total) |
+-------------------------+------------+
| Comic Con               |         8  |
+-------------------------+------------+

【问题讨论】:

  • 为什么你特别想避免使用LIMIT
  • 我不想硬编码结果
  • 我不明白你所说的硬编码结果是什么意思。
  • 当然,我的问题不清楚。例如,如果 2 行具有相同的值,则 limit 将只返回一个。我不确定什么是最好的解决方案
  • 是的,这是有道理的。现在您有两个答案,具体取决于您的 MySQL 版本。

标签: mysql sql group-by sql-order-by greatest-n-per-group


【解决方案1】:

如果您运行的是 MySQL 8.0,则可以使用 rank() 处理顶级关系:

select title, cnt_manager
from (
    select 
        p.title, 
        count(*) as cnt_manager,
        rank() over(order by count(*) desc) rn
    from project2manager pm
    join project p on pm.projectid = p.projectid 
    group by p.projectid, p.title
) t
where rn = 1

请注意,我将您的查询修改如下:

  • 除非project2manager 中的某些记录有manageridnull,否则count(project2manager.managerid) 可以缩短为count(*)

  • 表别名使查询更易于编写和阅读

  • 您似乎想按项目对数据进行分组;如果是这样,您不应该只关注项目title - 如果两个不同的项目具有相同的标题怎么办?为了避免这种情况,我在group by 子句中添加了projectid

【讨论】:

    【解决方案2】:

    尝试直接解决方案:

    SELECT project.title, 
           COUNT(project2manager.managerid) AS Cnt_Manager
    FROM project2manager 
    JOIN project ON project2manager.projectid = project.projectid 
    GROUP BY project.title
    HAVING NOT EXISTS ( SELECT NULL
                        FROM project2manager p2m
                        JOIN project p ON p2m.projectid = p.projectid 
                        GROUP BY p.title
                        HAVING COUNT(p2m.managerid) >= Cnt_Manager )
    

    对于版本 8+,使用 CTE 执行相同操作。

    【讨论】:

      猜你喜欢
      • 2021-09-21
      • 1970-01-01
      • 2013-08-06
      • 1970-01-01
      • 1970-01-01
      • 2012-02-17
      • 2021-02-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多