【SQL】按字段分组查询符合条件记录的方法
2016-10-08 01:51
1371 查看
SQL查询中经常会碰到这样一种情形:先按若干字段GROUP BY分组后,再以分组数据为基础,查询返回符合条件的记录。对于这种需求,简单情况下可以直接采用MAX/MIN函数配搭GROUP BY实现(方法一);但复杂一点的情况,则可以考虑SUBSTRING_INDEX(用法参考个人译文:http://blog.csdn.net/sweeper_freedoman/article/details/52716963)嵌套GROUP_CONCAT(用法参考个人译文:http://blog.csdn.net/sweeper_freedoman/article/details/52717263)的方法实现,即先聚合再截取(方法二)。
如示例表“visitor_province_day”数据所示,记录游客在每个省驻留的天数。
select * from visitor_province_day;
如果想知道每个游客驻留天数的极大值,可以简单地采用方法一。
SELECT vpd.visitor, MAX(vpd.`day`)
FROM visitor_province_day AS vpd
GROUP BY vpd.visitor;
方法一是最常见的查询需要,而且已经满足绝大多数情况下的查询需求。但是如果想知道每个游客(对于一张比较大的表)在哪两个省驻留时间最长,即分组后返回的结果多余1个(当然等于1也可以只是直接用方法一就可以了)就需要先按游客(visitor)分组,然后返回两个极大天数(day)所对应的省份(province)。首先GROUP_CONCAT聚合,结果返回游客和按照天数降序排序的省份集合。
SELECT vpd.visitor, GROUP_CONCAT(vpd.province ORDER BY vpd.day DESC)
FROM visitor_province_day AS vpd
GROUP BY vpd.visitor;
然后通过SUBSTRING_INDEX截取省份集合里面的前两个子集就实现查询需求了。
SELECT vpd.visitor, SUBSTRING_INDEX(GROUP_CONCAT(vpd.province ORDER BY vpd.day DESC), ',', 2)
FROM visitor_province_day AS vpd
GROUP BY vpd.visitor;
实际操作中的查询需要千变万化,按具体情况修改一下查询即可。当然其实在上面的例子中也可以直接按照默认(升序)排序然后截取最后两个子集(SUBSTRING_INDEX的最后一个参数替换为“-2”),即写法是多种多样的。这里推荐按返回需要降序排列的写法:GROUP_CONCAT操作超过MySQL系统变量“group_concat_max_len”以及“ max_allowed_packet”的设置会发生截断的情况,所以默认(升序)排序处理可能出现隐性的查询ERROR!
SELECT vpd.visitor, SUBSTRING_INDEX(GROUP_CONCAT(vpd.province ORDER BY vpd.day), ',', -2)
FROM visitor_province_day AS vpd
GROUP BY vpd.visitor;
如示例表“visitor_province_day”数据所示,记录游客在每个省驻留的天数。
select * from visitor_province_day;
+---------+-----------+-----+ | visitor | province | day | +---------+-----------+-----+ | 1 | 陕西省 | 5 | | 1 | 河北省 | 2 | | 1 | 浙江省 | 9 | | 11 | 浙江省 | 7 | | 11 | 江苏省 | 3 | | 11 | 湖南省 | 1 | | 11 | 福建省 | 4 | | 11 | 陕西省 | 1 | | 11 | 浙江省 | 5 | | 11 | 广东省 | 9 | | 11 | 陕西省 | 11 | +---------+-----------+-----+
如果想知道每个游客驻留天数的极大值,可以简单地采用方法一。
SELECT vpd.visitor, MAX(vpd.`day`)
FROM visitor_province_day AS vpd
GROUP BY vpd.visitor;
+---------+----------------+ | visitor | MAX(vpd.`day`) | +---------+----------------+ | 1 | 9 | | 11 | 11 | +---------+----------------+
方法一是最常见的查询需要,而且已经满足绝大多数情况下的查询需求。但是如果想知道每个游客(对于一张比较大的表)在哪两个省驻留时间最长,即分组后返回的结果多余1个(当然等于1也可以只是直接用方法一就可以了)就需要先按游客(visitor)分组,然后返回两个极大天数(day)所对应的省份(province)。首先GROUP_CONCAT聚合,结果返回游客和按照天数降序排序的省份集合。
SELECT vpd.visitor, GROUP_CONCAT(vpd.province ORDER BY vpd.day DESC)
FROM visitor_province_day AS vpd
GROUP BY vpd.visitor;
+---------+---------------------------------------------------------------------------------+ | visitor | GROUP_CONCAT(vpd.province ORDER BY vpd.day DESC) | +---------+---------------------------------------------------------------------------------+ | 1 | 浙江省,陕西省,河北省 | | 11 | 陕西省,广东省,浙江省,浙江省,福建省,江苏省,陕西省,湖南省 | +---------+---------------------------------------------------------------------------------+
然后通过SUBSTRING_INDEX截取省份集合里面的前两个子集就实现查询需求了。
SELECT vpd.visitor, SUBSTRING_INDEX(GROUP_CONCAT(vpd.province ORDER BY vpd.day DESC), ',', 2)
FROM visitor_province_day AS vpd
GROUP BY vpd.visitor;
+---------+---------------------------------------------------------------------------+ | visitor | SUBSTRING_INDEX(GROUP_CONCAT(vpd.province ORDER BY vpd.day DESC), ',', 2) | +---------+---------------------------------------------------------------------------+ | 1 | 浙江省,陕西省 | | 11 | 陕西省,广东省 | +---------+---------------------------------------------------------------------------+
实际操作中的查询需要千变万化,按具体情况修改一下查询即可。当然其实在上面的例子中也可以直接按照默认(升序)排序然后截取最后两个子集(SUBSTRING_INDEX的最后一个参数替换为“-2”),即写法是多种多样的。这里推荐按返回需要降序排列的写法:GROUP_CONCAT操作超过MySQL系统变量“group_concat_max_len”以及“ max_allowed_packet”的设置会发生截断的情况,所以默认(升序)排序处理可能出现隐性的查询ERROR!
SELECT vpd.visitor, SUBSTRING_INDEX(GROUP_CONCAT(vpd.province ORDER BY vpd.day), ',', -2)
FROM visitor_province_day AS vpd
GROUP BY vpd.visitor;
+---------+-----------------------------------------------------------------------+ | visitor | SUBSTRING_INDEX(GROUP_CONCAT(vpd.province ORDER BY vpd.day), ',', -2) | +---------+-----------------------------------------------------------------------+ | 1 | 浙江省,陕西省 | | 11 | 陕西省,广东省 | +---------+-----------------------------------------------------------------------+
相关文章推荐
- sql语句查询出表里符合条件的第二条记录的方法
- sql语句查询出表里符合条件的第二条记录的方法
- SQL中分组函数的使用及前N条记录的查询方法
- 将SQL查询分组后获得的结果中的某字段按照条件相加
- 用SQL查询数据库中某一字段下相同值的记录方法
- 找出所有符合条件的记录的指定字段并分组统计个数,返回指定格式。
- [MS SQL]SQL语句查询每个分组的前N条记录的实现方法
- Microsoft SQL Server中条件字段是Nvarchar类型的,条件有中文的无法查询的原因及处理方法
- 用SQL语句查询数据库中某一字段下相同值的记录方法
- SQL查询数据库中符合条件的记录的总数
- Sql 查询一个表中符合条件的且某一项为最大的记录
- sql根据某一字段查询不重复记录,同时要查询出所有满足条件的字段信息
- 用SQL语句查询数据库中某一字段下相同值的记录方法
- 查询数据库中指定字段符合条件的记录数
- SQL语句查询每个分组的前N条记录的实现方法
- 将SQL查询分组后获得的结果中的某字段按照条件相加
- 用SQL语句查询数据库中某一字段下相同值的记录方法
- 筛选同时符合多个字段指定条件记录的SQL
- 用sql语句,将两个字段合并,并当做条件进行查询的方法
- SQL重复记录查询 查询多个字段、多表查询、删除重复记录的方法