MySql下實現先排序後分組

2021-08-18 10:38:07 字數 3149 閱讀 2020

最近在工作中遇到乙個先排序後分組的需求,發現mysql不同的版本有不同的結果,特此記錄。

舉例:要求在shop表中查詢出各型別商店中**最高的商品。

--表結構--

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');

那麼很自然地就想到了對**price進行排序然後再根據商店型別shop_name進行分組查詢

select * from (select * from shop order

by price desc) a group

by a.shop_name

這條sql很簡單易懂,接下來我們驗證一下是否正確:

期望結果:

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變形記

最後放上相應的解決辦法:

--方法一,僅適用於低於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;

方法二中使用limit,需要limit的範圍足夠大能包括所有資料,並且每種分類只會顯示一條資料,但是資料較多時執行效率要比方法三快上很多,方法三能夠控制每種分類顯示多少條資料,把n換成需要顯示對應的數字即可。

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 結果 發現,並不能滿足我們需...