lag與lead函數是跟偏移量相關的兩個分析函數
通過這兩個函數可以在一次查詢中取出同一字段的前N行的數據(lag)和后N行的數據(lead)作為獨立的列,從而更方便地進行進行數據過濾
該操作可代替表的自聯接,且效率更高
lag()/lead()
lead(field, num, defaultvalue)
field: 需要查找的字段
num: 往后查找的num行的數據
defaultvalue: 沒有符合條件的默認值
over()
表示lag()與lead()操作的數據都在over()的范圍內,里面可以使用以下子句
partition by 語句(用於分組)
order by 語句()用於排序)
如:over(partition by a order by b) 表示以a字段進行分組,再以b字段進行排序,對數據進行查詢
示例:
數據集
with dataset as ( select '001' as id, 'Jack' as name, '大連' as city, '100' as sales from dual union all select '002' as id, 'Tom' as name, '大連' as city, '98' as sales from dual union all select '003' as id, 'John' as name, '大連' as city, '125' as sales from dual union all select '004' as id, 'Larry' as name, '大連' as city, '130' as sales from dual union all select '005' as id, 'Levi' as name, '沈陽' as city, '115' as sales from dual union all select '006' as id, 'Tomas' as name, '沈陽' as city, '170' as sales from dual union all select '007' as id, 'Jimmy' as name, '沈陽' as city, '130' as sales from dual union all select '008' as id, 'Robert' as name, '大連' as city, '103' as sales from dual union all select '009' as id, 'William' as name, '大連' as city, '118' as sales from dual union all select '010' as id, 'Joe' as name, '沈陽' as city, '108' as sales from dual )
獲取當前記錄的員工id,及銷量僅次於該員工的員工id
select t.id , lead(t.id, 1, null) over(order by t.sales desc) next_record_id, t.name, t.city, t.sales from ( select id, name, city, to_number(sales) as sales from dataset ) t
結果:
獲取當前記錄的員工id,及銷量僅高於該員工的員工id
select t.id , lag(t.id, 1, null) over(order by t.sales desc) next_record_id, t.name, t.city, t.sales from ( select id, name, city, to_number(sales) as sales from dataset ) t
結果:
獲取當前記錄的員工id,及按照城市分組且銷量僅次於該員工的員工id
select t.id , lead(t.id, 1, null) over(partition by t.city order by t.sales desc) next_record_id, t.name, t.city, t.sales from ( select id, name, city, to_number(sales) as sales from dataset ) t
結果:
獲取當前記錄的員工id,及按照城市分組且銷量僅次於該員工的員工id(銷量差小於10的忽略)
select tt.* from ( select t.id, t.name, t.sales, lead(t.sales,1, null) over(partition by t.city order by sales desc ) next_sales, (t.sales - lead(t.sales,1, null) over(partition by t.city order by sales desc )) as diff, t.city from ( select id, name, city, to_number(sales) as sales from dataset ) t ) tt where tt.diff >= 10 or tt.diff is null
結果: