日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql 窗口函数最新一条_MySQL 8.0 窗口函数(window functions)

發(fā)布時間:2024/7/23 数据库 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql 窗口函数最新一条_MySQL 8.0 窗口函数(window functions) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

窗口函數(shù)(window functions)是數(shù)據(jù)庫的標準功能之一,主流的數(shù)據(jù)庫比如Oracle,PostgreSQL都支持窗口函數(shù)功能,MySQL 直到 8.0 版本才開始支持窗口函數(shù)。

窗口函數(shù),簡單來說就是對于一個查詢SQL,將其結(jié)果集按指定的規(guī)則進行分區(qū),每個分區(qū)可以看作是一個窗口,分區(qū)內(nèi)的每一行,根據(jù)其所屬分區(qū)內(nèi)的行數(shù)據(jù)進行函數(shù)計算,獲取計算結(jié)果,作為該行的窗口函數(shù)結(jié)果值。

窗口函數(shù)與group聚合查詢類似,都是對一組(分區(qū))記錄進行計算,區(qū)別在于group對一組記錄計算后返回一條記錄作為結(jié)果,而窗口函數(shù)對一組記錄計算后,這組記錄中每條數(shù)據(jù)都會對應一個結(jié)果。

來看一個例子:

mysql> SELECT

year, country, product, profit,

SUM(profit) OVER() AS total_profit,

SUM(profit) OVER(PARTITION BY country) AS country_profit

FROM sales

ORDER BY country, year, product, profit;

+------+---------+------------+--------+--------------+----------------+

| year | country | product | profit | total_profit | country_profit |

+------+---------+------------+--------+--------------+----------------+

| 2000 | Finland | Computer | 1500 | 7535 | 1610 |

| 2000 | Finland | Phone | 100 | 7535 | 1610 |

| 2001 | Finland | Phone | 10 | 7535 | 1610 |

| 2000 | India | Calculator | 75 | 7535 | 1350 |

| 2000 | India | Calculator | 75 | 7535 | 1350 |

| 2000 | India | Computer | 1200 | 7535 | 1350 |

| 2000 | USA | Calculator | 75 | 7535 | 4575 |

| 2000 | USA | Computer | 1500 | 7535 | 4575 |

| 2001 | USA | Calculator | 50 | 7535 | 4575 |

| 2001 | USA | Computer | 1200 | 7535 | 4575 |

| 2001 | USA | Computer | 1500 | 7535 | 4575 |

| 2001 | USA | TV | 100 | 7535 | 4575 |

| 2001 | USA | TV | 150 | 7535 | 4575 |

+------+---------+------------+--------+--------------+----------------+

查詢SQL通過 OVER 子句來標記窗口,OVER 子句中的內(nèi)容可以指定窗口分區(qū)的方法。

上述例子中,第一個 OVER 子句中的參數(shù)為空,則將整個查詢結(jié)果集作為一個單一的分區(qū),分區(qū)內(nèi)的每條記錄的窗口函數(shù)計算結(jié)果為整個分區(qū)內(nèi)的字段值求和。

第二個 OVER子 句使用 country 字段作為參數(shù),對查詢結(jié)果集進行分區(qū),按照 country 分區(qū),分區(qū)內(nèi)求和,作為該分區(qū)內(nèi)每條記錄的窗口函數(shù)計算結(jié)果。

二、窗口函數(shù)語法

over_clause:

{OVER (window_spec) | OVER window_name}

window_spec:

[window_name] [partition_clause] [order_clause] [frame_clause]

partition_clause:

PARTITION BY expr [, expr] ...

order_clause:

ORDER BY expr [ASC|DESC] [, expr [ASC|DESC]] ...

如果 OVER() 子句里面的內(nèi)容為空,則窗口大小為整個查詢的結(jié)果集,使用結(jié)果集中的所有記錄計算結(jié)果。

如果 OVER() 子句里面的內(nèi)容不為空,則使用里面指定的窗口分區(qū)規(guī)則、排序規(guī)則對分區(qū)內(nèi)的記錄進行分區(qū)和排序。

partition_clause,指定如何對查詢結(jié)果集進行分區(qū),窗口函數(shù)基于分區(qū)內(nèi)的記錄進行計算,如果沒有指定 partition_clause 子句,則對整個查詢結(jié)果集數(shù)據(jù)進行計算。SQL標準要求 PARTITION BY 后面只能跟字段名,MySQL擴展支持表達式,比如ts字段為TIMESTAMP類型,可以這樣使用PARTITION BY HOUR(ts)。

order_clause,可選,后面可以跟 ASC?或者?DESC 指定排序方向。order by 子句對分區(qū)內(nèi)的記錄進行排序。

frame_clause,表示當前分區(qū)的一個子集,frame_clause 指定了定義當前分區(qū)子集的方法。

三、命名的窗口

窗口函數(shù)的窗口能夠使用指定的名稱來定義,然后可以在 OVER 子句中使用指定的名稱來引用窗口。

舉個例子,未使用命名窗口的窗口函數(shù)如下:

SELECT

val,

ROW_NUMBER() OVER (ORDER BY val) AS 'row_number',

RANK() OVER (ORDER BY val) AS 'rank',

DENSE_RANK() OVER (ORDER BY val) AS 'dense_rank'

FROM numbers;

使用命名窗口改寫,如下:

SELECT

val,

ROW_NUMBER() OVER w AS 'row_number',

RANK() OVER w AS 'rank',

DENSE_RANK() OVER w AS 'dense_rank'

FROM numbers

WINDOW w AS (ORDER BY val);

使用命名的窗口,SQL更加清晰、簡潔,更容易測試窗口的定義,如果要修改窗口的定義,只需要修改WINDOW子句,而不必每個OVER子句都修改。

四、非聚合類窗口函數(shù)

MySQL支持的非聚合類窗口函數(shù)如下:

CUME_DIST()

DENSE_RANK()

FIRST_VALUE() LAG()

LAST_VALUE()

LEAD() NTH_VALUE()

NTILE()

PERCENT_RANK()

RANK() ,

ROW_NUMBER()

舉個例子,通過ROW_NUMBER()函數(shù),計算每條記錄在其所在分區(qū)內(nèi)的行號。默認條件下,分區(qū)內(nèi)的記錄是未排序的,因此行號也是不確定的,可以使用 order by 子句對窗口函數(shù)定義的分區(qū)內(nèi)的數(shù)據(jù)集進行排序。下面例子 row_num1?未排序,row_num2 排序。

mysql> SELECT

year, country, product, profit,

ROW_NUMBER() OVER(PARTITION BY country) AS row_num1,

ROW_NUMBER() OVER(PARTITION BY country ORDER BY year, product) AS row_num2

FROM sales;

+------+---------+------------+--------+----------+----------+

| year | country | product | profit | row_num1 | row_num2 |

+------+---------+------------+--------+----------+----------+

| 2000 | Finland | Computer | 1500 | 2 | 1 |

| 2000 | Finland | Phone | 100 | 1 | 2 |

| 2001 | Finland | Phone | 10 | 3 | 3 |

| 2000 | India | Calculator | 75 | 2 | 1 |

| 2000 | India | Calculator | 75 | 3 | 2 |

| 2000 | India | Computer | 1200 | 1 | 3 |

| 2000 | USA | Calculator | 75 | 5 | 1 |

| 2000 | USA | Computer | 1500 | 4 | 2 |

| 2001 | USA | Calculator | 50 | 2 | 3 |

| 2001 | USA | Computer | 1500 | 3 | 4 |

| 2001 | USA | Computer | 1200 | 7 | 5 |

| 2001 | USA | TV | 150 | 1 | 6 |

| 2001 | USA | TV | 100 | 6 | 7 |

+------+---------+------------+--------+----------+----------+

另外一個例子,CUME_DIST() 函數(shù),計算分區(qū)內(nèi),小于等于當前值的記錄數(shù)占分區(qū)內(nèi)總記錄數(shù)的比值,取值范圍為0~1。示例如下:

mysql> SELECT

val,

ROW_NUMBER() OVER w AS 'row_number',

CUME_DIST() OVER w AS 'cume_dist',

PERCENT_RANK() OVER w AS 'percent_rank'

FROM numbers

WINDOW w AS (ORDER BY val);

+------+------------+--------------------+--------------+

| val | row_number | cume_dist | percent_rank |

+------+------------+--------------------+--------------+

| 1 | 1 | 0.2222222222222222 | 0 |

| 1 | 2 | 0.2222222222222222 | 0 |

| 2 | 3 | 0.3333333333333333 | 0.25 |

| 3 | 4 | 0.6666666666666666 | 0.375 |

| 3 | 5 | 0.6666666666666666 | 0.375 |

| 3 | 6 | 0.6666666666666666 | 0.375 |

| 4 | 7 | 0.8888888888888888 | 0.75 |

| 4 | 8 | 0.8888888888888888 | 0.75 |

| 5 | 9 | 1 | 1 |

+------+------------+--------------------+--------------+

五、聚合類窗口函數(shù)

窗口函數(shù)的 OVER 子句可以和許多聚合函數(shù)一起使用,這些聚合函數(shù)加上 OVER 子句,就是窗口函數(shù),如果不加 OVER 子句,就是普通的聚合函數(shù)。支持窗口函數(shù)功能的聚合函數(shù)如下:

AVG()

BIT_AND()

BIT_OR()

BIT_XOR()

COUNT()

JSON_ARRAYAGG()

JSON_OBJECTAGG()

MAX()

MIN()

STDDEV_POP(), STDDEV(), STD()

STDDEV_SAMP()

SUM()

VAR_POP(), VARIANCE()

VAR_SAMP()

本文開頭的第一個例子,就是使用SUM()聚合函數(shù)做窗口計算的,可以翻回去看一下。

六、窗口函數(shù)的使用限制

SQL標準加在窗口函數(shù)上的一個限制是不能用于update和delete語句來更新行記錄。在update和delete語句的子查詢中使用窗口函數(shù)是允許的。

不支持聚合窗口函數(shù)的 DISTINCT?語法

不支持嵌套的窗口函數(shù)

不支持依賴于當前行值的動態(tài)幀結(jié)束點

指定 GROUPS?幀單元能夠被解析,但是會產(chǎn)生錯誤,僅支持 ROWS?和 RANGE

指定幀的 EXCLUDE?子句能夠被解析,但是會產(chǎn)生錯誤

IGNORE NULLS 子句能夠被解析,但是會產(chǎn)生錯誤,目前只支持 RESPECT NULLS 子句

FROM LAST 子句能夠被解析,但是會產(chǎn)生錯誤,目前只支持 FROM FIRST 子句

總結(jié)

以上是生活随笔為你收集整理的mysql 窗口函数最新一条_MySQL 8.0 窗口函数(window functions)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。