mysql 開窗函式 累加 mysql實現開窗函式

2021-10-17 13:36:00 字數 2788 閱讀 4663

學習過oracle的應該知道,oracle中的分析函式功能十分強大,包括mssql、postgresql等資料庫都支援開窗函式。然而mysql至今都沒有提供這樣的功能,今天就來**下用mysql實現一些開窗功能需求。

實驗資料:表sale

| month  | user_id | amount |

| 201601 | 1       |    500 |

| 201601 | 2       |    300 |

| 201601 | 3       |    100 |

| 201602 | 1       |   1000 |

| 201602 | 2       |    800 |

| 201603 | 2       |   1000 |

| 201603 | 3       |    500 |

| 201604 | 1       |   1000 |

需求一:求每個月的銷售額及累計銷售額(二月份額累計銷售額是一月銷售額加二月銷售額)

開窗函式實現:

select month,sum(amount),sum(sum(amount)) over (order by month) from sale group by month order by month

month  | sum  | sum

201601 |  900 |  900

201602 | 1800 | 2700

201603 | 1500 | 4200

201604 | 1000 | 5200

輕鬆完成需求

mysql實現:

select

a.month,a.amount,sum(b.amount)

from (select month,sum(amount) amount from sale group by month) a cross join (select month,sum(amount) amount from sale group by month) b

where a.month>=b.month group by a.month,a.amount

| month  | amount | sum(b.amount) |

| 201601 |    900 |           900 |

| 201602 |   1800 |          2700 |

| 201603 |   1500 |          4200 |

| 201604 |   1000 |          5200 |

可以看出相比較於開窗函式,mysql實現起來很麻煩,先用子查詢將每個月的銷售彙總,再將兩個子查詢做笛卡爾積,效能肯定比開窗差很多,如果子查詢結果集很多,做笛卡爾積是個災難!

需求二:每個月銷售冠軍及銷售額

開窗函式實現:

select month,user_id,amount

from

(select

month,user_id,amount,

row_number() over (partition by month order by amount desc) rn

from sale) a where a.rn=1

month  | user_id | amount

201601 | 1       |    500

201603 | 2       |   1000

201602 | 1       |   1000

201604 | 1       |   1000

mysql實現:

方法一:

select a.*

from (select t1.*,

(select count(*) + 1

from sale

where month = t1.month

and amount > t1.amount) as group_id

from sale t1) a

where a.group_id = 1;

| month  | user_id | amount | group_id |

| 201601 | 1       |    500 |        1 |

| 201603 | 2       |   1000 |        1 |

| 201602 | 1       |   1000 |        1 |

| 201604 | 1       |   1000 |        1 |

這個樣的方式同樣是用笛卡爾積得出和開窗rank一樣的結果列出來

方法二:

select month,user_id,max(amount) from sale group by month

| month  | user_id | max(amount) |

| 201601 | 1       |         500 |

| 201602 | 1       |        1000 |

| 201603 | 2       |        1000 |

| 201604 | 1       |        1000 |

mysql實現起來簡單,但是注意,這個語句是不嚴謹的,因為user_id沒有跟在group by後面,這是其他資料庫所不允許。在mysql5.6中預設的sql_mode只有no_engine_substitutio,這樣的語法可以使用,如果sql_mode有only_full_group_by的限制,則無法使用這樣的語法。mysql5.7的sql_mode就預設含有only_full_group_by。

mysql開窗函式有哪些 mysql開窗函式

開窗函式 它可以理解為記錄集合,開窗函式也就是在滿足某種條件的記錄集合上執行的特殊函式。對於每條記錄都要在此視窗內執行函式,有的函式隨著記錄不同,視窗大小都是固定的,這種屬於靜態視窗 有的函式則相反,不同的記錄對應著不同的視窗,這種動態變化的視窗叫滑動視窗。開窗函式的本質還是聚合運算,只不過它更具靈...

mysql實現開窗函式

mysql實現開窗函式 學習過oracle的應該知道,oracle中的分析函式功能十分強大,包括mssql postgresql等資料庫都支援開窗函式。然而mysql至今都沒有提供這樣的功能,今天就來 下用mysql實現一些開窗功能需求。實驗資料 表sale month user id amount...

MySql實現ROW NUMBER 開窗函式

本文咱們使用mysql實現開窗函式row number over partition by order by 廢話不多說,直接開幹 準備資料select from test biz policy policy platform id 平台id publish time 政策發布時間 policy n...