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...