简体   繁体   English

从SQL中的联接中选择持有最大值的多行

[英]Selecting multiple rows holding a max value from a join in sql

I've read multiple other posts about a similar issue on here, but none of them seem to answer my problem. 我在这里阅读了有关类似问题的其他多篇文章,但似乎都没有答案。

I have a table, works_on, which contains all of the hours from a project that employees have worked on: 我有一张表works_on,其中包含员工从事的项目的所有时间:

     id     pno  hours

 123456789   1   32.50
 123456789   2    7.50
 333445555   2   10.00
 333445555   3   10.00 
 333445555  10   10.00
 ...

And another table, project, giving the name of each of the corresponding project numbers (pno) in the works_on table: 还有另一个表project,在works_on表中给出了每个相应项目编号(pno)的名称:

   pname           pno  location 

 ProductX           1   Bellaire 
 ProductY           2   Sugarland
 ProductZ           3   Houston
 Computerization   10   Stafford
...

I'm trying to get the name(s) of the project(s) with the highest aggregate hours WITHOUT using a SELECT TOP or LIMIT constraint, as we don't know how many "max" values there are. 我正在尝试不使用SELECT TOP或LIMIT约束而获得总计总小时数最高的项目的名称,因为我们不知道有多少个“ max”值。

I'm able to aggregate the hours as such: 我可以这样汇总小时数:

SELECT p.pname, sub.hours FROM company.project p
JOIN
    (SELECT w.pno, SUM(IFNULL(w.hours, 0)) AS hours FROM company.works_on w
     GROUP BY w.pno) AS sub
ON p.pnumber = sub.pno;

Returning the result: 返回结果:

   pname           hours      

 ProductX          52.50
 ProductY          37.50
 ProductZ          50.00
 Computerization   55.00
 Reorganization    25.00
 Newbenefits       55.00

ie, computerization and newbenefits should be ideally returned, as they have the highest aggregate hours, but I can't seem to execute a MAX query that gives me this result. 也就是说,理想情况下应该返回计算机化和新收益 ,因为它们具有最高的合计小时数,但是我似乎无法执行给出此结果的MAX查询。

Is there a workaround to this to select the max result without the use of a TOP or SORT/LIMIT constraint? 是否有解决方法,可以在不使用TOP或SORT / LIMIT约束的情况下选择最大结果?

This is tough to do in MySQL without the help of analytic functions. 如果没有分析功能的帮助,在MySQL中很难做到这一点。 Here is one way: 这是一种方法:

SELECT p.pname, sub.hours
FROM company.project p
INNER JOIN
(
    SELECT pno, SUM(hours) AS hours
    FROM company.works_on
    GROUP BY pno
) sub
    ON p.pnumber = sub.pno
WHERE
    sub.hours = (SELECT SUM(hours) FROM company.works_on
                 GROUP BY pno ORDER BY SUM(hours) DESC LIMIT 1);

If you are using MySQL 8+ or later, then we can take advantage of RANK() : 如果您使用的是MySQL 8+或更高版本,则可以利用RANK()

SELECT pname, hours
FROM
(
    SELECT p.pname, sub.hours,
        RANK() OVER (PARTITION BY p.pname ORDER BY sub.hours DESC) rnk
    FROM company.project p
    INNER JOIN
    (
        SELECT pno, SUM(hours) AS hours
        FROM company.works_on
        GROUP BY pno
    ) sub
) t
WHERE rnk = 1;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM