使用MySQL會話變量實現窗口函數

1、MySQL窗口函數服務器

 (1) 序號函數session

     row_number()在相等的兩條記錄上隨機排序,但序號按照一、2遞增,而後後面的序號繼續遞增爲3,中間不會產生序號間隙;函數

      rank()/dense_rank()則把前兩條相等的記錄序號都設置爲1,但後續則分別設置爲3(rank)和2(dense_rank)。即rank()會產生序號相同的記錄,同時可能產生序號間隙;而dense_rank()也會產生序號相同的記錄,但不會產生序號間隙。url

 

 

 (2) 分佈函數.net

    percent_rank()blog

  • 用途:和以前的RANK()函數相關,每行按照以下公式進行計算:
  • (rank - 1) / (rows - 1)
  • 其中,rank爲RANK()函數產生的序號,rows爲當前窗口的記錄總行數
  • 應用場景:本行序號在該組內所佔的位置百分比(不多用)。

 

 

 cume_dist()排序

  • 用途:分組內小於等於當前rank值的行數/分組內總行數,這個函數比percen_rank使用場景更多。
  • 應用場景:大於等於當前訂單金額的訂單比例有多少

 (3) 先後函數進程

先後函數——lead(n)/lag(n)。作用域

  • 用途:分區中位於當前行前n行(lead)/後n行(lag)的記錄值。
  • 使用場景:查詢上一個訂單距離當前訂單的時間間隔。

SQL以下:文檔

內層SQL先經過lag函數獲得上一次訂單的日期,外層SQL再將本次訂單和上次訂單日期作差獲得時間間隔diff。

 (4) 頭尾函數

頭尾函數——first_val(expr)/last_val(expr)。

  • 用途:獲得分區中的第一個/最後一個指定參數的值。
  • 使用場景:查詢截止到當前訂單,按照日期排序第一個訂單和最後一個訂單的訂單金額。

SQL以下:

結果和預期一致,好比order_id爲4的記錄,first_amount和last_amount分別記錄了用戶‘001’截止到時間2018-01-03 00:00:00爲止,第一條訂單金額100和最後一條訂單金額800,注意這裏是按時間排序的最先訂單和最晚訂單,並非最小金額和最大金額訂單。

 (5) 其餘函數

其餘函數——nth_value(expr,n)/nfile(n)。

nth_value(expr,n)

  • 用途:返回窗口中第N個expr的值,expr能夠是表達式,也能夠是列名。
  • 應用場景:每一個用戶訂單中顯示本用戶金額排名第二和第三的訂單金額。

SQL以下:

nfile(n)

  • 用途:將分區中的有序數據分爲n個桶,記錄桶號。
  • 應用場景:將每一個用戶的訂單按照訂單金額分紅3組。

SQL以下:

此函數在數據分析中應用較多,好比因爲數據量大,須要將數據平均分配到N個並行的進程分別計算,此時就能夠用NFILE(N)對數據進行分組,因爲記錄數不必定被N整除,因此數據不必定徹底平均,而後將不一樣桶號的數據再分配。

 (6) 聚合函數做爲窗口函數

  • 用途:在窗口中每條記錄動態應用聚合函數(sum/avg/max/min/count),能夠動態計算在指定的窗口內的各類聚合函數值。
  • 應用場景:每一個用戶按照訂單id,截止到當前的累計訂單金額/平均訂單金額/最大訂單金額/最小訂單金額/訂單數是多少?

SQL以下:

除了這幾個經常使用的聚合函數,還有一些也可使用,好比BIT_AND()、STD()等等,具體查看官方文檔。

 2、MySQL變量

MySQL入門 SQL語言之十八:系統變量(全局變量、會話變量),自定義變量(用戶變量、局部變量)的使用
#變量
/*
系統變量:
    全局變量
    會話變量
自定義變量:
    用戶變量
    局部變量
*/
#1、系統變量
/*
說明:變量由系統提供,不是用戶定義,屬於服務器層面
使用的語法:
一、查看全部的系統變量
show global variables;
SHOW session VARIABLES;#session能夠省略

二、查看知足條件的部分系統變量
show VARIABLES variables like '%char%';

三、查看指定的某個系統變量值
select @@global|【session】.系統變量名;

四、爲某個系統變量賦值
方式一:
set global|【session】 系統變量名 = 值;
set autocommit = 0;

方式二:
set @@global|【session】.系統變量名 = 值;

注意:
若是是全局級別,則須要加global,若是是會話級別,則須要加session,若是不寫,則默認session

*/
#1》、全局變量
/*
做用域:服務器每次啓動將爲全部的全局變量賦初始值,針對於全部會話(鏈接)有效,可是不能跨重啓。
若是要想每次啓動也修改,則須要修改配置文件。
*/
#①查看全部的全局變量
SHOW GLOBAL VARIABLES;

#②查看部分的全局變量
SHOW GLOBAL VARIABLES LIKE '%char%';

#③查看指定的全局量的值
SELECT @@global.autocommit;
SELECT @@tx_isolation;

#④爲某個指定全局變量賦值
#方式一:
SET @@global.autocommit = 0;
#方式二:
SET GLOBAL autocommit = 0;
#2》、會話變量
/*
做用域:僅僅針對於當前會話(鏈接)有效,而且有默認值
*/


#①查看全部的會話變量;
SHOW SESSION VARIABLES;
SHOW  VARIABLES;

#②查看部分的會話變量
SHOW  VARIABLES LIKE '%char%';
SHOW SESSION VARIABLES  LIKE '%char%';

#③查看指定的某個會話變量
SELECT @@tx_isolation;
SELECT @@session.tx_isolation;

#④爲某個會話變量賦值
#方式一
SET @@session.tx_isolation = 'read-uncommitted';
#方式二:
SET SESSION tx_isolation =  'read-committed';


#2、自定義變量
/*
說明:變量是用戶自定義的,不是由系統的

使用步驟
聲明
賦值
使用(查看、比較、運算等)
*/
#一、用戶變量
/*
做用域:針對於當前會話(鏈接)有效,同於會話變量的做用域
應用在任何地方,也就是begin end裏面或begin end外邊
*/
賦值的操做符: = 或 :=
#①聲明並初始化
SET @用戶變量名 = 值;
SET @用戶變量名 := 值;
SELECT @用戶變量名 :=值;

#②賦值(更新用戶變量的值)
方式一: 經過SET或SELECT
    SET @用戶變量名 = 值;
    SET @用戶變量名 := 值;
    SELECT @用戶變量名 :=值;
方式二:經過SELECT INTO
    SELECT 字段 INTO @變量名
    FROM 表;
#③使用(查看用戶變量名的值)    
SELECT @用戶變量名;

#二、局部變量
/*
做用域:僅僅在定義它的begin end中有效
應用在begin end中的第一句話
*/
#①聲明
DECLARE 變量名 類型;
DECLARE 變量名 類型 DEFAULT 值;
#②賦值
方式一: 經過SET或SELECT
    SET 局部變量名 = 值;
    SET 局部變量名 := 值;
    SELECT @局部變量名 :=值;
方式二:經過SELECT INTO 局部變量名
    SELECT 字段
#③使用
SELECT 局部變量名;


    
#案例:
#聲明並初始化
SET @name = 'john';
SET @name = 100;
SET @count = 1;
#賦值
SELECT COUNT(*) INTO @count 
FROM employees;
#查看
SELECT @count;


對比用戶變量和局部變量

  做用域 定義和使用的位置  語法
用戶變量 當前的會話 會話中的任何地方 必須加@符號,不限定類型
局部變量  BEGIN END中 只能在BEGIN END中,且爲第一句 通常不加@符號,需限定類型
 

#案例:聲明兩個變量並賦初始值,就和,並打印
#1.用戶變量
SET @m=1;
SET @n=2;
SET @sum = @m+@n;
SELECT @sum;
#2.局部變量
    DECLARE m INT DEFAULT 1;
    DECLARE n INT DEFAULT 2;
    DECLARE SUM INT;
    SET SUM = m + n;
    SELECT SUM;

#報錯


本文轉載自:

http://www.sohu.com/a/260324504_411876

https://blog.csdn.net/qq_34626097/article/details/86528466;

相關文章
相關標籤/搜索