mysql 求分组最大值的十个解法

发布时间:2020-08-08 23:32:28

来源:51CTO

阅读:1383

作者:努力的C

"How to solve the same problem in 10 different ways".

One of the common problems to solve in SQL is "Get row with the group-wise maximum". Getting just the maximum for the group is simple, getting the full row which is belonging to the maximum is the interesting step.

求每个分组的最大值也许简单,但是求出对应的最大值的所有信息却是一个非常有意思的话题。

SELECT MAX(population), continent

FROM Country

GROUP BY continent;

+-----------------+---------------+

| MAX(population) | continent |

+-----------------+---------------+

| 1277558000 | Asia |

| 146934000 | Europe |

| 278357000 | North America |

| 111506000 | Africa |

| 18886000 | Oceania |

| 0 | Antarctica |

| 170115000 | South America |

+-----------------+---------------+

We use the 'world' database from the MySQL manual for the examples.

我们试用了MySQL手册中的‘world’数据库作为测试

The next step is to find the countries which have the population and the continent of our gathered data.

下面我们就可以找到一条数据对应的全部数据

***SELECT continent, name, population

FROM Country

WHERE population = 1277558000

AND continent = 'Asia';

+-----------+-------+------------+

| continent | name | population |

+-----------+-------+------------+

| Asia | China | 1277558000 |

+-----------+-------+------------+

Instead of doing this row by row we just do a JOIN between the two by using a temporary table:

为避免一行一行的搜索,我们可以建一个临时表,然后使用join操作

CREATE TEMPORARY TABLE co2

SELECT continent, MAX(population) AS maxpop

FROM Country

GROUP BY continent;

SELECT co1.continent, co1.name, co1.population

FROM Country AS co1, co2

WHERE co2.continent = co1.continent

AND co1.population = co2.maxpop;*

+---------------+----------------------------------------------+------------+

| continent | name | population |

+---------------+----------------------------------------------+------------+

| Oceania | Australia | 18886000 |

| South America | Brazil | 170115000 |

| Asia | China | 1277558000 |

| Africa | Nigeria | 111506000 |

| Europe | Russian Federation | 146934000 |

| North America | United States | 278357000 |

| Antarctica | Antarctica | 0 |

| Antarctica | Bouvet Island | 0 |

| Antarctica | South Georgia and the South Sandwich Islands | 0 |

| Antarctica | Heard Island and McDonald Islands | 0 |

| Antarctica | French Southern territories | 0 |

+---------------+----------------------------------------------+------------+

DROP TEMPORARY TABLE co2;

删除临时表;

Instead of using a temporary table as internal steps we can write the same also as simple sub-query which is creating a temporary table internally.

当然了,我们也可以使用子查询代替临时表

*SELECT co1.continent, co1.name, co1.population

FROM Country AS co1,

(SELECT continent, MAX(population) AS maxpop

FROM Country

GROUP BY continent) AS co2

WHERE co2.continent = co1.continent

and co1.population = co2.maxpop;***

+---------------+----------------------------------------------+------------+

| continent | name | population |

+---------------+----------------------------------------------+------------+

| Oceania | Australia | 18886000 |

| South America | Brazil | 170115000 |

| Asia | China | 1277558000 |

| Africa | Nigeria | 111506000 |

| Europe | Russian Federation | 146934000 |

| North America | United States | 278357000 |

| Antarctica | Antarctica | 0 |

| Antarctica | Bouvet Island | 0 |

| Antarctica | South Georgia and the South Sandwich Islands | 0 |

| Antarctica | Heard Island and McDonald Islands | 0 |

| Antarctica | French Southern territories | 0 |

+---------------+----------------------------------------------+------------+

The sub-query is executed in the exact same way as the temporary table we created by hand. Instead of JOINing against the temporary table we JOIN against the result of the sub-query.

Hmm, this was too simple ? Let's take a look at the alternatives:

SELECT co1.continent, co1.name, co1.population

FROM Country AS co1

WHERE co1.population =

(SELECT MAX(population) AS maxpop

FROM Country AS co2

WHERE co2.continent = co1.continent);

To be read as: 'Get the countries which have the same population as the maximum population of the current country'. Using such a sub-qeury results in more readable sub-queries. BUT ... they a 'DEPENDENT' as the inner query is refering to a field of the outer query. This means that for each row of the outer query the inner query is executed.

The same query can be written in two other ways:

SELECT continent, name, population

FROM Country

WHERE ROW(population, continent) IN (

SELECT MAX(population), continent

FROM Country

GROUP BY continent);

SELECT co1.continent, co1.name, co1.population

FROM country as co1

WHERE co1.population >= ALL

(SELECT co2.population

FROM country AS co2

WHERE co2.continent = co1.continent);

If you don't want to use sub-queries and prefer pure JOINs perhaps there are for you:

SELECT co1.continent, co1.name, co1.population

FROM country AS co1 LEFT JOIN country AS co2

ON co1.population < co2.population AND

co1.continent = co2.continent

WHERE co2.population is NULL;

SELECT co1.Continent, co1.Name

FROM Country AS co1 JOIN Country AS co2

ON co2.Continent = co1.Continent AND

co1.Population <= co2.Population

GROUP BY co1.Continent, co1.Name

HAVING COUNT(*) = 1

added 2005-05-28 as no. 11, sent in by rudy@r937.com

SELECT co1.continent, co1.name

FROM Country AS co1 JOIN Country AS co2

ON co1.continent = co2.continent

GROUP BY co1.continent, co1.name

HAVING co1.population = MAX(co2.population)

Now you already know 8 ways. The last two shall only give you some more ideas. First of all a way that doesn't work (yet).

SELECT co2.continent, MAX(co2.population) AS maxpop,

(SELECT name

FROM Country

WHERE population = maxpop AND

continent = co2.continent)

FROM Country AS co2

GROUP BY co2.continent;

ERROR 1247 (42S22): Reference 'maxpop' not supported (reference to group function)

And as the last one the modified max-concat example from the manual.

SELECT continent,

SUBSTRING( MAX( CONCAT(LPAD(population,10,'0'),name) ), 10+1) AS name,

MAX( population ) AS population

FROM Country

GROUP BY continent;

The result is slightly different but it is more about the idea.

MySQL各部门求最值_mysql 求分组最大值的十个解法相关推荐

  1. mysql case 2个返回值_MySQL函数简介 2

    6.5 条件判断函数 条件判断函数也被称为控制流程函数,根据满足的条件的不同,执行相应的流程,Mysql中进行条件判断的有IF,IFNULL,和CASE. 6.5.1 IF(expr,v1,v2)函数 ...

  2. mysql求月平均_mysql求平均值

    表结构: create table monitor ( instanceId varchar(100) not null, date date not null, cloud varchar(20) ...

  3. mysql怎么约束指定默认值_mysql 默认值约束

    "默认值(Default)"的完整称呼是"默认值约束(Default Constraint)".MySQL 默认值约束用来指定某列的默认值. 例如女性同学较多, ...

  4. 下列有关mysql数据库中的null值_MySQL数据库中与 NULL值有关的问题

    对于SQL的新手,NULL值的概念常常会造成混淆,他们常认为NULL是与空字符串"相同的事.情况并非如此.例如,下述语句是完全不同的: mysql> INSERT INTO my_ta ...

  5. mysql查询为0的值_MySql查询整型字段空字符时出现为0的数据

    表结构: -- 表的ddl CREATE TABLE `user_desc` ( `ID` int(11) NOT NULL AUTO_INCREMENT, `USER_NAME` varchar(2 ...

  6. mysql 事务 返回插入的值_Mysql同一个事务内记录成功插入后查询不出来

    背景: 1)mysql:Ver 14.12 Distrib 5.0.45, for Win32 (ia32) 2)mysql odbc驱动:3.51.22 3)vs2005 4)客户端用ado,odb ...

  7. mysql无效的时间默认值_mysql – ‘timestamp’的默认值无效

    我在我的数据库中收到错误.我遇到时间戳的无效默认值. 这是我的数据库: CREATE TABLE IF NOT EXISTS `post` ( `id` int(11) NOT NULL, `text ...

  8. mysql计算相邻的差值_MySQL如何计算相邻两行某列差值

    MySQL计算相邻两行某列差值的方法:首先通过[r1.rownum = r2.rownum - 1]来判断两条记录是否是前后行:然后再使用TIMEDIFF函数来计算时间差即可. [相关学习推荐:mys ...

  9. mysql中筛选不重复值_MYSQL中筛选不重复记录值的示例

    我的wordpress数据库中的wp_postmeta表都有10,000多行了,如果使用两次循环查找判断,虽然我们不累,但是程序运行很累啊. 如果我想用一条语句查询得到name不重复的所有数据,那就必 ...

最新文章

  1. .bash_profile 写入时间格式YYYY-MM-DD HH24:MI:SS 时报错 not a valid identifier
  2. 各大银行对应的字段(仅做参考)
  3. jQuery学习笔记系列(三)——事件注册、事件处理、事件对象、拷贝对象、多库共存、jQuery插件、toDoList综合案例
  4. javascript this的意思
  5. Mifare l卡特性简介
  6. QBXT Day 4 数学,数论
  7. Linux 文件系统启动记录
  8. smart原则_写给中学生:用SMART原则制定寒假计划
  9. form表单钩子,局部钩子和全局钩子
  10. 2014年domino学习小结
  11. GDOI2018滚粗记
  12. 关于营销自动化,30个惊人的事实
  13. C++常函数的用法详解
  14. 叶胜超:跨链双雄之Cosmos(宇宙)
  15. 【第三方互联】4、分享至腾讯QQ、新浪微博(sina)
  16. 【Prometheus】Alertmanager告警全方位讲解
  17. 选用pg的优点和缺点
  18. (转)使用Wireshark抓包软件提示The NPF driver isn’t running解决办法
  19. FreeNAS家庭工作存储搭建指南(一)——硬件篇
  20. 智能问答系统一些思考——四类方法

热门文章

  1. Active MQ的安装
  2. 1342. 断开的项链【难度: 一般 / 破环成链】
  3. Zookeeper下载
  4. Bootstrap的目录结构
  5. 【SpringMVC 之应用篇】 1_SpringMVC入门 —— 第一个 Spring MVC 程序
  6. 后端生成Token架构与设计详解
  7. 如何更规范化编写 Java 代码
  8. 05-JDBC连接MySQL数据库【删除数据】
  9. 一天搞定HTML----a标签02
  10. Java IO流之转换流