最近在工作中遇到乙個先排序後分組的需求,發現mysql不同的版本有不同的結果,特此記錄。
舉例:要求在shop表中查詢出各型別商店中**最高的商品。
那麼很自然地就想到了對**price進行排序然後再根據商店型別shop_name進行分組查詢--表結構--
create
table
`shop` (
`id`
int (10) primary
key,
`shop_name`
varchar (100),
`item_name`
varchar (100),
`price`
int (10)
);insert
into
`shop` (`id`, `shop_name`, `item_name`,`price`) values('1','小賣部','醬油','12');
insert
into
`shop` (`id`, `shop_name`, `item_name`,`price`) values('2','小賣部','醋','15');
insert
into
`shop` (`id`, `shop_name`, `item_name`,`price`) values('3','小賣部','脈動','20');
insert
into
`shop` (`id`, `shop_name`, `item_name`,`price`) values('4','小賣部','沙薑','2');
insert
into
`shop` (`id`, `shop_name`, `item_name`,`price`) values('5','超市','豬肉','24');
insert
into
`shop` (`id`, `shop_name`, `item_name`,`price`) values('6','超市','生菜','6');
insert
into
`shop` (`id`, `shop_name`, `item_name`,`price`) values('7','超市','菜心','5');
insert
into
`shop` (`id`, `shop_name`, `item_name`,`price`) values('8','連鎖店','生薑','3');
insert
into
`shop` (`id`, `shop_name`, `item_name`,`price`) values('9','超市','牛肉','30');
insert
into
`shop` (`id`, `shop_name`, `item_name`,`price`) values('10','連鎖店','蒜頭','2');
insert
into
`shop` (`id`, `shop_name`, `item_name`,`price`) values('11','連鎖店','黃瓜','20');
這條sql很簡單易懂,接下來我們驗證一下是否正確:select * from (select * from shop order
by price desc) a group
by a.shop_name
期望結果:
mysql 5.7.20下的實際結果:
可以看出來實際上得出的結果只是按照表資料的順序,簡單地進行了分組查詢操作,但是這時候我們還不能下結論說這條sql就是錯誤的,我們用另乙個資料庫版本(mysql 5.5.57)測試一下。
mysql 5.5.57下的結果:
我們分別檢視一下這條sql在兩個不同版本資料庫的執行計畫:
對比可以發現5.7版本的mysql在執行這條sql時缺少了乙個derived操作,通過查閱相關資料了解到mysql 5.7對子查詢進行了優化,認為子查詢中的order by可以進行忽略,只要derived table裡不包含如下條件就可以進行優化:
union clause
group by
distinct
aggregation
limit or offset
這裡把鏈結放上:5.7中derived table變形記
最後放上相應的解決辦法:
方法二中使用limit,需要limit的範圍足夠大能包括所有資料,並且每種分類只會顯示一條資料,但是資料較多時執行效率要比方法三快上很多,方法三能夠控制每種分類顯示多少條資料,把n換成需要顯示對應的數字即可。--方法一,僅適用於低於5.7版本的mysql--
select * from (select * from shop order
by price desc) a group
by a.shop_name;
--方法二--
select * from (select * from shop order
by price desc limit 999999) a group
by a.shop_name;
--方法三--
select * from shop a where n > (select
count(*) from shop b where b.shop_name = a.shop_name and a.price < b.price) order
by a.shop_name,a.price desc;
mybatis先排序後分組
1.乙個統計資料的需求是取每個月資料,並展示當月的總值 因為展示該月總值的話,需要展示該月中記錄時間最大的作為展示 故先要進行排序後再分組 select if sd.tx type 1,sum sd.tx vb 0 as txvb,if sd.tx type 0,sum sd.tx vb 0 as ...
mysql先排序後分組方法
直接上sql select c.from select a.id,a.longitude,a.latitude,b.state,b.id as bid from event t room info a left join event.t active b on a.id b.room id and ...
mysql 先排序再分組的sql語句實現
最近專案中有乙個需求,需要先分組,再排序的功能。搞了好久,經過敏大大 後台兄弟 指導,終於搞出來了,分享給大家 demo 學生資訊表 第一時間想到 sql select from t test group by name,type order by score desc 結果 發現,並不能滿足我們需...