MySQL視窗函式基礎初試(一)

2021-10-02 06:15:59 字數 4725 閱讀 7737

mysql支援視窗函式,對於資料row的查詢,會使用一些相關的rows進行計算出乙個row。如下將會討論如何使用視窗函式,包括over以及window子句,本結只討論非聚集視窗函式。聚集視窗函式參考:聚集視窗函式 。更多關於優化以及視窗函式參考:視窗函式優化 。mysql視窗函式主要涉及一下內容:

12.21.1 window function descriptions

12.21.2 window function concepts and syntax

12.21.3 window function frame specification

12.21.4 named windows

12.21.5 window function restrictions

mysql8版本開始支援視窗函式,豐富的一些複雜邏輯的開發,示例**如下:

show create table open_id_to_pin;

create table `open_id_to_pin`

( `id` int not null auto_increment,

`open_id` varchar(32) default null,

`pin` varchar(32) default null,

`expire_time` datetime default null,

primary key (`id`)

) engine = innodb

default charset = utf8;

insert into open_id_to_pin (id, open_id, pin, expire_time) values (1, 'aa', 'a_zs', '2019-01-17 11:31:04');

insert into open_id_to_pin (id, open_id, pin, expire_time) values (2, 'aa', 'a_ln', '2021-01-17 11:31:28');

insert into open_id_to_pin (id, open_id, pin, expire_time) values (3, 'bb', 'bb_1', '2021-01-17 11:31:50');

insert into open_id_to_pin (id, open_id, pin, expire_time) values (4, 'aa', 'a_sd', '2021-01-17 11:31:28');

insert into open_id_to_pin (id, open_id, pin, expire_time) values (5, 'cc', 'c_sd', '2021-01-17 11:31:28');

insert into open_id_to_pin (id, open_id, pin, expire_time) values (6, 'cc', 'c_cc', '2021-01-17 11:31:29');

-- cume_dist() cume_dist:計算某個值在一組有序的資料中累計的分布

# 計算結果為相對位置/總行數,返回值為(0,1]

# 注意:對於重複值,計算的時候,取重複值的最後一行的位置

select *, cume_dist() over (partition by open_id order by expire_time desc )

from open_id_to_pin;

---- rank

select *, rank() over (partition by open_id order by expire_time desc )

from open_id_to_pin;

--select *, dense_rank() over (partition by open_id order by expire_time desc )

from open_id_to_pin;

-- first_value 取分組內排序後,截止到當前行,第乙個值

select *, first_value(pin) over (partition by open_id order by expire_time desc )

from open_id_to_pin;

-- last_value 取分組內排序後,截止到當前行,最後乙個值

select *, last_value(pin) over (partition by open_id order by expire_time desc )

from open_id_to_pin;

-- lag(col,n,default) 用於統計視窗內往上第n行值 第乙個引數為列名,第二個引數為往上第n行(可選,預設為1),第三個引數為預設值(當往上第n行為null時候,取預設值,如不指定,則為null)

select *, lag(pin, 1, null) over (partition by open_id order by expire_time )

from open_id_to_pin;

-- lead 與lag相反 lead(col,n,default) 用於統計視窗內往下第n行值 第乙個引數為列名,第二個引數為往下第n行(可選,預設為1),第三個引數為預設值(當往下第n行為null時候,取預設值,如不指定,則為null)

select *, lead(pin, 1, null) over (partition by open_id order by expire_time)

from open_id_to_pin;

-- nth_value() 返回視窗的第n行

select *, nth_value(pin, 2) over (partition by open_id order by expire_time desc)

from open_id_to_pin;

-- ntile 劃分分組,將視窗內部的劃分為n組,也可以叫做n個bucket

select *, ntile(3) over (partition by open_id order by expire_time desc)

from open_id_to_pin;

-- percent_rank計算邏輯:(rank - 1) / (rows - 1)

# 計算方法為(相對位置-1)/(總行數-1)

# 注意:對於重複值,計算的時候,取重複值的第一行的位

select *, percent_rank() over (partition by open_id order by expire_time desc)

from open_id_to_pin;

-- 對於視窗生成臨時表的寫法

select *, rank() over w

from open_id_to_pin

window w as (partition by open_id order by expire_time desc );

# 計算行號

select @rownum := @rownum + 1 as rownum,

e.*from (select @rownum := 0) r,

open_id_to_pin e;

#相關子查詢

select *

from open_id_to_pin a

where a.expire_time in (select max(b.expire_time) from open_id_to_pin b where a.open_id = b.open_id)

# 視窗函式實現openid相同取最新的記錄

select *

from (select *, row_number() over (partition by open_id order by expire_time desc ) as rn

from open_id_to_pin

) tab

where tab.rn = 1;

# ---------------------------------

# 相同點:rank()和dense_rank()的是排名函式

# 不同點:rank()是跳躍排序,即如果有兩條記錄重複,接下來是第**別

# 如:1 2 2 4,會跳過3

# dense_rank()是連續排序,即如果有兩條記錄重複,接下來是第二級別

# 如:1 2 2 3

# 按照open_id劃分視窗以及按照 exipre_time 排序

select *, rank() over (partition by open_id order by expire_time desc) as rk

from open_id_to_pin;

select *, dense_rank() over (partition by open_id order by expire_time desc) as rk

from open_id_to_pin;

# 按照open_id劃分視窗以及按照open_id排序

select *, rank() over (partition by open_id order by open_id desc) as rk

from open_id_to_pin;

select *, dense_rank() over (partition by open_id order by open_id desc) as rk

from open_id_to_pin;

官方參考:

初試MySQL筆記之一

mysql是乙個關係型資料庫管理系統 rdbms mysql的非商業應用是免費的。乙個資料庫可以包含若干個表 table 每個表的每一行 row 資料由若干個資料域 field 或者叫做資料列 column 組成的。連線mysql mysql h hostname u username p 然後輸入...

MySQL 視窗函式高階處理

視窗函式種類 練習題參考 視窗函式也稱為olap函式。olap 是online analyticalprocessing 的簡稱,意思是對資料庫資料進行實時分析處理。為了便於理解,稱之為視窗函式。常規的select語句都是對整張表進行查詢,而視窗函式可以讓我們有選擇的去某一部分資料進行彙總 計算和排...

MySQL視窗函式的使用

1.from 2.where 3.group by.sum h ing.4.select 5.order by 計算兩個date型之間的天數差 注意 結果是前 後,如果想得到正數差,截止時間放前面 計算兩日期時間之間相差的天數,秒數,分鐘數,週數,小時數,這裡主要分享的是通過mysql內建的函式 t...