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

COMMIT;

更新于: 2020年12月5日

90 次查看

启动您的 职业生涯

通过完成课程获得认证

开始
广告