如何在 Oracle 中訪問前一行或後一行的值?


您想使用 Oracle 聚合函式 XMLAGG 進行字串聚合嗎?

解決方案

您希望在結果集中包含基於前一行和後一行的計算。

Oracle 支援 LAG 和 LEAD 分析函式來訪問表中的多行,利用前導或後繼邏輯,您無需將源資料自連線。為了演示用法,我們將使用學生資料。

LAG 函式可用於檢視哪個學生/s 的加入跟隨另一個學生,以及計算加入之間經過的時間。

SQL:識別學生的加入資訊

示例

SELECT first_name,       last_name,       join_date,       lag(join_date, 1, '01-JAN-2001') OVER (ORDER BY join_date)             AS prev_join_data,       join_date - lag(join_date, 1, '01-JAN-2001') OVER (ORDER BY join_date) AS join_date_diff FROM students ORDER BY join_date;

輸出

|first_name | last_name | join_date | prev_join_data | joining_date_diff | ---       | ---        | ---       |  ---          |  --- | WILLIAMS   |ROBERT      |13/JAN/01      |01/JAN/01      |12 WILSON      |THOMAS      |16/AUG/02      |13/JAN/01      |580 RODRIGUEZ   |JOSEPH      |17/AUG/0      2|16/AUG/02      |1 SMITH      |JAMES      |17/JUN/03      |17/AUG/02      |304 MILLER      |DAVID      |25/JUN/05      |17/JUN/03      |739 JOHNSON      |JOHN      |21/SEP/05      |25/JUN/05      |88 MARTINEZ      |CHRISTOPHER|28/SEP/05      |21/SEP/05   |7 ANDERSON      |DANIEL      |30/SEP/05      |28/SEP/05   |2 BROWN      |MICHAEL      |03/JAN/06      |30/SEP/05   |95 DAVIS      |RICHARD      |05/FEB/06      |03/JAN/06   |33 TAYLOR      |PAUL      |07/MAR/06      |05/FEB/06   |30 GARCIA      |CHARLES      |07/FEB/07   |07/MAR/06   |337 JONES      |WILLIAM      |21/MAY/07   |07/FEB/07   |103 THOMAS      |MARK      |07/DEC/07   |21/MAY/07      |200

LAG 和 LEAD 函式與大多數其他分析函式類似,它們在查詢的非分析部分完成後才執行。Oracle 對中間結果集進行第二次遍歷以應用任何分析謂詞。

LEAD 函式的工作方式與 LAG 函式相同,但它跟蹤後續行而不是前導行。

為了演示,我們將顯示連線以及下一個學生的 join_date,以及他們在 joindates 之間類似的經過時間視窗。

示例

SELECT first_name  ,       last_name  ,       join_date   ,       lead(join_date, 1, sysdate) OVER (ORDER BY join_date)              AS next_join_date   ,       lead(join_date, 1, sysdate) OVER (ORDER BY join_date) -  join_date  AS days_between_join FROM students ORDER BY join_date

輸出

名字
姓氏
加入日期
下一個加入日期
加入日期之間的天數
WILLIAMS
ROBERT
01年1月13日
02年8月16日
580
WILSON
THOMAS
02年8月16日
02年8月17日
1
RODRIGUEZ
JOSEPH
02年8月17日
03年6月17日
304
SMITH
JAMES
03年6月17日
05年6月25日
739
MILLER
DAVID
05年6月25日
05年9月21日
88
JOHNSON
JOHN
05年9月21日
05年9月28日
7
MARTINEZ
CHRISTOPHER
05年9月28日
05年9月30日
2
ANDERSON
DANIEL
05年9月30日
06年1月3日
95
BROWN
MICHAEL
06年1月3日
06年2月5日
33
DAVIS
RICHARD
06年2月5日
06年3月7日
30
TAYLOR
PAUL
06年3月7日
07年2月7日
337
GARCIA
CHARLES
07年2月7日
07年5月21日
103
JONES
WILLIAM
07年5月21日
07年12月7日
200
THOMAS
MARK
07年12月7日
20年11月27日
4739.08978009259259259259259259259259259

資料準備:問題使用的資料如下所示。

示例

DROP TABLE students;
COMMIT;

CREATE TABLE students
    ( student_id     NUMBER(6)
    , first_name     VARCHAR2(20)
    , last_name      VARCHAR2(25)
    , email          VARCHAR2(40)
    , phone_number   VARCHAR2(20)
    , join_date      DATE
    , class_id       VARCHAR2(20)  
    , fees           NUMBER(8,2)
    , professor_id   NUMBER(6)
    , department_id  NUMBER(4)
    ) ;

示例

CREATE UNIQUE INDEX stu_id_pk ON students (student_id) ;
INSERT INTO students VALUES (100,'SMITH','JAMES','SMITH.JAMES@notreal.com','111.111.1245',TO_DATE('17-06-2003','DD-MM-YYYY'),'INS_CHAIRMAN',24000,NULL,NULL);
INSERT INTO students VALUES (101,'JOHNSON','JOHN','JOHNSON.JOHN@notreal.com','111.111.1246',TO_DATE('21-09-2005','DD-MM-YYYY'),'INS_VP',17000,100,90);
INSERT INTO students VALUES (102,'WILLIAMS','ROBERT','WILLIAMS.ROBERT@notreal.com','111.111.1247',TO_DATE('13-01-2001','DD-MM-YYYY'),'INS_VP',17000,100,90);
INSERT INTO students VALUES (103,'BROWN','MICHAEL','BROWN.MICHAEL@notreal.com','111.111.1248',TO_DATE('03-01-2006','DD-MM-YYYY'),'INS_STAFF',9000,102,60);
INSERT INTO students VALUES (104,'JONES','WILLIAM','JONES.WILLIAM@notreal.com','111.111.1249',TO_DATE('21-05-2007','DD-MM-YYYY'),'INS_STAFF',6000,103,60);
INSERT INTO students VALUES (105,'MILLER','DAVID','MILLER.DAVID@notreal.com','111.111.1250',TO_DATE('25-06-2005','DD-MM-YYYY'),'INS_STAFF',4800,103,60);
INSERT INTO students VALUES (106,'DAVIS','RICHARD','DAVIS.RICHARD@notreal.com','111.111.1251',TO_DATE('05-02-2006','DD-MM-YYYY'),'INS_STAFF',4800,103,60);
INSERT INTO students VALUES (107,'GARCIA','CHARLES','GARCIA.CHARLES@notreal.com','111.111.1252',TO_DATE('07-02-2007','DD-MM-YYYY'),'INS_STAFF',4200,103,60);
INSERT INTO students VALUES (108,'RODRIGUEZ','JOSEPH','RODRIGUEZ.JOSEPH@notreal.com','111.111.1253',TO_DATE('17-08-2002','DD-MM-YYYY'),'CL_PHY',12008,101,100);
INSERT INTO students VALUES (109,'WILSON','THOMAS','WILSON.THOMAS@notreal.com','111.111.1254',TO_DATE('16-08-2002','DD-MM-YYYY'),'CL_MATH',9000,108,100);
INSERT INTO students VALUES (110,'MARTINEZ','CHRISTOPHER','MARTINEZ.CHRISTOPHER@notreal.com','111.111.1255',TO_DATE('28-09-2005','DD-MM-YYYY'),'CL_MATH',8200,108,100);
INSERT INTO students VALUES (111,'ANDERSON','DANIEL','ANDERSON.DANIEL@notreal.com','111.111.1256',TO_DATE('30-09-2005','DD-MM-YYYY'),'CL_MATH',7700,108,100);
INSERT INTO students VALUES (112,'TAYLOR','PAUL','TAYLOR.PAUL@notreal.com','111.111.1257',TO_DATE('07-03-2006','DD-MM-YYYY'),'CL_MATH',7800,108,100);
INSERT INTO students VALUES (113,'THOMAS','MARK','THOMAS.MARK@notreal.com','111.111.1258',TO_DATE('07-12-2007','DD-MM-YYYY'),'CL_MATH',6900,108,100);

COMMIT;

更新於: 2020年12月5日

90 次檢視

啟動您的 職業生涯

透過完成課程獲得認證

開始
廣告

© . All rights reserved.