前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MySQL 组内排序

MySQL 组内排序

作者头像
lukachen
发布2023-10-22 15:26:37
1090
发布2023-10-22 15:26:37
举报
文章被收录于专栏:LukaChen BlogLukaChen Blog

在开发中经常遇到这样一类需求:取每种类型排名前几的数据。在此我简称它为组内排序。 以下,我借鉴了别人的方法并添加自己的想法,就这类问题做一下理解:

数据准备

代码语言:javascript
复制
CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `type` varchar(255) DEFAULT NULL,
  `variety` varchar(255) DEFAULT NULL,
  `price` decimal(10,2) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

insert into test(type,variety,price) 
values
('apple','gala',2.79),
('apple','fuji',0.24),
('apple','limbertwig',2.87),
('orange','valencia',3.59),
('orange','navel',9.36),
('pear','bradford',6.05),
('pear','bartlett',2.14),
('cherry','bing',2.55),
('cherry','chelan',6.33),
('cherry','own',1.03);

1.取每类最便宜的一种

1.1 子查询 select from ((select from test order by price asc) tmp) group by type;

1.2 UNION(类型少还能用,类型多或类型不定就算了吧) (select * from test where type = 'apple' order by price asc limit 1) UNION (select * from test where type = 'orange' order by price asc limit 1) UNION (select * from test where type = 'pear' order by price asc limit 1) UNION (select * from test where type = 'cherry' order by price asc limit 1);

1.3 子查询 where (coung(*)) < 1

  • select from test a where (select count() from test b where a.type = b.type and b.price < a.price) = 0;
  • select from test a where (select count() from test b where a.type = b.type and b.price < a.price) < 1;

针对1.3的解读: 1).where (count(*)) = 0 以apple为例:

  • test a 中 id = 1 price = 2.79, test b 取 type = apple 且价格比 2.79 小的个数为 0 个 //不成立因为 id = 2 price = 0.24 比 2.79 小, count(*) = 1;
  • test a 中 id = 2 price = 0.24, test b 取 type = apple 且价格比 0.24 小的个数为 0 个 //成立因为在 type = apple 中没有一个 price 小于 0.24, count(*) = 0,其他类型以此类推.

2).where (count(*)) < 1 以apple为例:

  • test a 中 id = 1 price = 2.79, test b 取 type = apple 且价格比 2.79 小的个数小于 1 个 //不成立因为 id = 2 price = 0.24 比 2.79 小, count(*) = 1;
  • test a 中 id = 2 price = 0.24, test b 取 type = apple 且价格比 0.24 小的个数小于 1 个 //成立因为在 type = apple 中没有一个 price 小于 0.24, count(*) < 1;

3).其他类型以此类推

2.取每类最便宜的两种

2.1 找出每类水果价格最便宜的两个品种,这时子查询就不能用了

2.2 UNION(类型少还能用,类型多或类型不定就算了吧) (select * from test where type = 'apple' order by price asc limit 2) UNION (select * from test where type = 'orange' order by price asc limit 2) UNION (select * from test where type = 'pear' order by price asc limit 2) UNION (select * from test where type = 'cherry' order by price asc limit 2);

2.3 子查询 where (coung(*)) < 2 select from test a where (select count() from test b where a.type = b.type and b.price < a.price) < 2;

针对2.3的解读: 1).where (count(*)) < 2 以apple为例:

  • test a 中 id = 1 price = 2.79, test b 取 type = apple 且价格比 2.79 小的个数小于 2 个 //成立因为 id = 2 price = 0.24 比 2.79 小, count(*) = 1 < 2;
  • test a 中 id = 2 price = 0.24, test b 取 type = apple 且价格比 0.24 小的个数小于 2 个 //成立因为在 type = apple 中没有一个 price 小于 0.24, count(*) = 0 < 2;
  • test a 中 id = 3 price = 2.87, test b 取 type = apple 且价格比 2.87 小的个数小于 2 个 //不成立因为在 type = apple 中 id = 1 price = 2.79 和 id = 2 price = 0.24 都小于 2.87, count(*) = 2 !< 2;

2).其他类型以此类推

总结一下:在 where 条件中关联本类型并 count(*) 的方法最为灵活,推荐使用这种方法来解此类问题。推荐方法并没有对每种类型中进行排序啊!说好的组内排序呢……,好吧在最外层套一个 order_by price asc 就好了,本文意在为这类问题提供解决方案,请不要在意这个细节 ^-^

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-04-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 数据准备
    • 1.取每类最便宜的一种
      • 2.取每类最便宜的两种
        • 总结一下:在 where 条件中关联本类型并 count(*) 的方法最为灵活,推荐使用这种方法来解此类问题。推荐方法并没有对每种类型中进行排序啊!说好的组内排序呢……,好吧在最外层套一个 order_by price asc 就好了,本文意在为这类问题提供解决方案,请不要在意这个细节 ^-^
        相关产品与服务
        云数据库 MySQL
        腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档