Article Directory
1 Overview
- and two lead lag function is a function of the analysis associated with the offset can take the same field in a query by these two functions the first N rows of data (lag) and the last N rows of data (lead) as an independent column , So as to more conveniently filter the data.
- This operation may also be represented for self-ligation , and greater efficiency.
2 Grammar
-- lag 和 lead 一样
lag(value_expr, [offset], [default]) over([partition by ..] order by ..)
(1) value_expr: 字段名
(2) offset: 偏移量 -> N 默认 1
(3) default: 字段值超出偏移量时的默认值,默认为 null
3 Examples
Example 1: Get the id of the current record, the id of the previous record, and the id of the next record
WITH t_test AS (
SELECT 1 ID, 'a' NAME, '男' sex FROM dual UNION ALL
SELECT 2 ID, 'b' NAME, '女' sex FROM dual UNION ALL
SELECT 3 ID, 'c' NAME, '女' sex FROM dual UNION ALL
SELECT 4 ID, 'd' NAME, '女' sex FROM dual UNION ALL
SELECT 5 ID, 'e' NAME, '男' sex FROM dual
)
SELECT t.id,
LAG(t.id, 1, NULL) OVER(ORDER BY t.id) previous_id,
LEAD(t.id, 1, NULL) OVER(ORDER BY t.id) next_id,
t.name,
t.sex
FROM t_test t;
Test Results:
Example 2: Get the id of the current record, the id of the previous record and the id of the next record with the same "gender"
WITH t_test AS (
SELECT 1 ID, 'a' NAME, '男' sex FROM dual UNION ALL
SELECT 2 ID, 'b' NAME, '女' sex FROM dual UNION ALL
SELECT 3 ID, 'c' NAME, '女' sex FROM dual UNION ALL
SELECT 4 ID, 'd' NAME, '女' sex FROM dual UNION ALL
SELECT 5 ID, 'e' NAME, '男' sex FROM dual
)
SELECT t.id,
LAG(t.id, 1, NULL) OVER(PARTITION BY t.sex ORDER BY t.id) previous_id,
LEAD(t.id, 1, NULL) OVER(PARTITION BY t.sex ORDER BY t.id) next_id,
t.name,
t.sex
FROM t_test t;
Test Results:
Example 3: Get records with the same "gender" and the id of the current record and the id of the next record differ by 2 or more
WITH t_test AS (
SELECT 1 ID, 'a' NAME, '男' sex FROM dual UNION ALL
SELECT 2 ID, 'b' NAME, '女' sex FROM dual UNION ALL
SELECT 3 ID, 'c' NAME, '女' sex FROM dual UNION ALL
SELECT 4 ID, 'd' NAME, '女' sex FROM dual UNION ALL
SELECT 5 ID, 'e' NAME, '男' sex FROM dual
)
SELECT tt.*
FROM (SELECT t.id,
lead(t.id, 1, NULL) over(PARTITION BY t.sex ORDER BY t.id) next_id,
t.name,
t.sex
FROM t_test t) tt
WHERE tt.next_id >= tt.id + 2;
Test Results: