SQL在不同维度上的多个最大值

时间:2018-11-06 23:19:34

标签: mysql

我正在尝试找到最大数量的值,但问题是即使值相等,我的代码也只选择最大值,所以我怎么能找到最大值,如果有相同值就排成两行

这里是示例: (注;数据是伪造的,仅是示例问题,如果出现问题,请让我)

select class.name as className, 
       school.schoolName as schoolName, 
       count(school.quantity) as totalNumber from class
join School on school.schoolName = class.schoolName
group by classname, schoolName
order by schoolName

结果是:

className | SchoolNAme | TotalNum 
 -----------|------------|---------- 
  Math      | A          |        9 
  Bio       | A          |        2 
  History   | A          |        7 
  Music     | A          |        9 
  Math      | B          |       22 
  English   | B          |        8 
  Music     | B          |        1 
  History   | B          |        2 
  Geo       | B          |        2 
  Bio       | B          |        3 
  Math      | C          |       15 
  Geo       | C          |        2 

我发现每个学校的最大人数是这样的:

select ClassName, 
       SchoolName, 
       max(totalNumber) as Total
from 
(
  select class.name as className, 
         school.schoolName as schoolName, 
         count(school.quantity) as totalNumber from class
  join School on school.schoolName = class.schoolName
  group by classname, schoolName
  order by schoolName
) t1
group by schoolName

这是我得到的结果:

className | SchoolNAme | Total 
 -----------|------------|---------- 
  Math      | A          |        9 
  Math      | B          |       22 
  Math      | C          |       15 

但是我遇到的问题是,9的两个总数是school A 因此,如果它们相等,我如何显示所有最大数目。

这就是我想要的;

className | SchoolNAme | Total
 -----------|------------|---------- 
  Math      | A          |        9 
  Bio       | A          |        9
  Math      | B          |       22 
  Math      | C          |       15 

谢谢

1 个答案:

答案 0 :(得分:0)

最大将每组显示1行,因为您按学校名称分组,如果有3所学校,您将获得3组,因此返回3行。

学校A类Bio从您的数据中看来只有2行( count 对每个组的行进行计数),因此Bio A 9将永远不会被返回,因此所需的结果将永远无法获得。我猜您真的希望音乐A 9代替以及 数学A 9

在这种情况下, School 表实际上是多余的(基于对联接和随后数据的解释,即count是对联接行的数量进行计数,从而对类行的数量进行计数。) >

因此,我相信以下内容会产生您所追求的结果:-

WITH 
    cte1 AS
        (SELECT name,schoolName, count() AS cnt FROM class
        GROUP BY name,schoolName),
    cte2 AS 
        (SELECT name, schoolName, max(cnt) AS m FROM cte1 
        GROUP BY schoolname)
-- SELECT * FROM cte2
SELECT cte1.name, cte1.schoolName, cte1.cnt FROM cte1  
WHERE cte1.cnt = (SELECT m FROM cte2 WHERE cte2.schoolname = cte1.schoolname)
ORDER BY schoolName, name
;

以上内容通过以下测试:-

DROP TABLE IF EXISTS school;
DROP TABLE IF EXISTS class;
CREATE TABLE IF NOT EXISTS school (schoolName TEXT, quantity INTEGER);
CREATE TABLE IF NOT EXISTS class (name TEXT, schoolName);
INSERT INTO school VALUES ('A',1),('B',1),('C',1);
INSERT INTO class VALUES 
('Math','A'),('Math','A'),('Math','A'),('Math','A'),('Math','A'),('Math','A'),('Math','A'),('Math','A'),('Math','A'),
('Bio','A'),('Bio','A'),
('History','A'),('History','A'),('History','A'),('History','A'),('History','A'),('History','A'),('History','A'),
('Music','A'),('Music','A'),('Music','A'),('Music','A'),('Music','A'),('Music','A'),('Music','A'),('Music','A'),('Music','A'),
('Math','B'),('Math','B'),('Math','B'),('Math','B'),('Math','B'),('Math','B'),('Math','B'),('Math','B'),('Math','B'),('Math','B'),('Math','B'),('Math','B'),('Math','B'),('Math','B'),('Math','B'),('Math','B'),('Math','B'),('Math','B'),('Math','B'),('Math','B'),('Math','B'),('Math','B'),
('English','B'),('English','B'),('English','B'),('English','B'),('English','B'),('English','B'),('English','B'),('English','B'),
('Music','B'),
('History','B'),('History','B'),
('Geo','B'),('Geo','B'),
('Bio','B'),('Bio','B'),('Bio','B'),
('Math','C'),('Math','C'),('Math','C'),('Math','C'),('Math','C'),('Math','C'),('Math','C'),('Math','C'),('Math','C'),('Math','C'),('Math','C'),('Math','C'),('Math','C'),('Math','C'),('Math','C'),
('Geo','C'),('Geo','C')
;



select class.name as className, school.schoolName as schoolName, count() as totalNumber from class
join School on school.schoolName = class.schoolName
group by classname, school.schoolName
order by schoolName, totalNumber DESC
;

select ClassName, SchoolName, max(totalNumber) as Total
from 
(
  select class.name as className, school.schoolName as schoolName, count(school.quantity) as totalNumber from class
    join School on school.schoolName = class.schoolName
    group by classname,school.schoolname
    order by schoolName
)
group by schoolName;

WITH 
    cte1 AS
        (SELECT name,schoolName, count() AS cnt FROM class
        GROUP BY name,schoolName),
    cte2 AS 
        (SELECT name, schoolName, max(cnt) AS m FROM cte1 
        GROUP BY schoolname)
-- SELECT * FROM cte2
SELECT cte1.name, cte1.schoolName, cte1.cnt FROM cte1  
WHERE cte1.cnt = (SELECT m FROM cte2 WHERE cte2.schoolname = cte1.schoolname)
ORDER BY schoolName, name
;

结果

首次查询

第一个查询是您的查询,结果与问题中的结果匹配:-

enter image description here

第二个查询

再次与您的问题中不想要/错误的结果相匹配:-

enter image description here

第三次查询

我相信这符合您的要求:-

enter image description here