Oracle的lag()函數(分析函數)的應用


 

 公交車上刷了一下知乎,看到一個問題:【怎么處理才能把左邊的表變成右邊?】

其實問題提問的很模糊,沒有業務描述,只說結果,接下來也就是按照答者的理解吧

答者認為該題需求:用戶連續訪問同一個頁面時,只保留最早的一條而已。

 

思路:我們冗余列來制作數據行之間的信息差,第一次我們需要明確數據的順序(知道前后),這里新增【用戶瀏覽時間序號】。
問題中消除重復,是為了消除同一個頁面連續訪問記錄只保留最早的一條,我們需要明確 用戶+頁面內的前后,
即【用戶瀏覽某頁面時間序號】, 即通過兩列信息差,我們可以找到自己想要的數據。

 

具體SQL邏輯如下:  第一步:在原始數據中通過冗余列制作信息差,作為數據篩選的依據: 

select 用戶,頁面,瀏覽時間,

ROW_NUMBER() OVER(PARTITION BY 用戶 ORDER BY 瀏覽時間 ASC) AS 用戶瀏覽時間序號,

ROW_NUMBER() OVER(PARTITION BY 用戶,頁面 ORDER BY 瀏覽時間 ASC) AS 用戶瀏覽某頁面時間序號

from 用戶瀏覽日志

  數據輸出:########### 結果集 

用戶,頁面,瀏覽時間,用戶瀏覽時間序號,用戶瀏覽某頁面時間序號

甲,1,a,1,1

甲,1,b,2,2

甲,1,c,3,3

甲,2,d,4,1

甲,1,e,5,4 

 第二步,基於有信息差的結果集,來篩選出自己想要的數據:

   select 用戶,頁面,瀏覽時間 from (select 用戶,頁面,瀏覽時間,

ROW_NUMBER() OVER(PARTITION BY 用戶 ORDER BY 瀏覽時間 ASC) AS 用戶瀏覽時間序號,

ROW_NUMBER() OVER(PARTITION BY 用戶,頁面 ORDER BY 瀏覽時間 ASC) AS 用戶瀏覽某頁面時間序號

from 用戶瀏覽日志) tt where tt.用戶瀏覽某頁面時間序號=1 or tt.用戶瀏覽時間序號<>tt.用戶瀏覽某頁面時間序號 

最終輸出:########### 結果集

  用戶,頁面,瀏覽時間

甲,1,a

甲,2,d

甲,1,e 

------------ 上述答案有漏洞--------------------- 

 

 

 

 

然后:

Youmple 提出:如果 甲~1~e 后面緊接着 甲~1~f ,那是不是 甲~1~f 也會進入結果集。那明顯是錯的啊

感謝評論指出了,這一版答案的漏洞,我們優化一下。 

我們可以余出一列:【前一頁瀏覽頁面】

  lag(頁面,1) OVER(PARTITION BY 用戶 ORDER BY 瀏覽時間 ASC) AS 前一頁瀏覽頁面。 

數據輸出: 

用戶,頁面,瀏覽時間,前一個瀏覽的頁面

甲,1,a,null

甲,1,b,1

甲,1,c,1

甲,2,d,1

甲,1,e,2

甲,1,f,1 

同時過濾的數據條件修改為:  where tt.頁面<> coalesce(tt.前一個瀏覽的頁面,0) 

 

 

 

 是不是很容易,只需要做兩次簡單的排序,就解決來問題。  遇到問題,要多思考,辦法肯定有,SQL一樣可以寫出花。

 

 原文:https://www.zhihu.com/question/496875292/answer/2210351015


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM