我想要检索开始日期和结束日期之间的数据,包括 Oracle SQL 中存在的每行数据的开始日期的前一行。忽略唯一 ID,因为它用于其他目的。
我的存储过程对于单个
inRollNumber
可以正常工作,提供之前的日期和开始到结束的日期数据。但是,当我将卷号留空并希望从数据库中检索所有数据时,它仅获取开始日期和结束日期之间的数据,而不是每个卷号的上一条记录。
存储过程代码:
PROCEDURE spGetReportData
(inEC varchar2 Default null,
inRollNumber varchar2 Default null,
inUserID varchar2 Default null,
inStartDate varchar2 Default null,
inEndDate varchar2 Default null,
inStatus varchar2,
inInternalStatus varchar2 Default null,
outcursor out CURSOR_REF)
AS
BEGIN
open outcursor for
select Result.*,Ut.FIRSTNAME ||' '||Ut.LASTNAME UserName,
CASE
WHEN ROW_NUMBER() OVER (PARTITION BY Result.rollnumber,Result.ec ORDER BY Result.ActivityDate ASC) > 2
THEN Result.rollnumber || '-' || Result.ec || '-' || (ROW_NUMBER() OVER (PARTITION BY Result.rollnumber,Result.ec ORDER BY Result.ActivityDate ASC) - 2)
ELSE Result.rollnumber || '-' || Result.ec
END UniqueId
from
(
select DAT1.*,
dat1.log_datetime ActivityDate
from TBLIRGLOG_TRANSACTION_DATA dat1
where
dat1.status=inStatus
AND DAT1.INTERNALSTATUS IN ('AC','CLIP', 'CLA4')
and (dat1.USERID =nvl(inUserID,dat1.USERID) or dat1.USERID IS NULL)
and (dat1.rollnumber =nvl(inRollNumber,dat1.rollnumber) or dat1.rollnumber IS NULL)
and (dat1.LOG_DATETIME >= nvl(inStartDate,dat1.LOG_DATETIME) OR dat1.LOG_DATETIME IS NULL)
and (dat1.LOG_DATETIME <= nvl(inEndDate,dat1.LOG_DATETIME) OR dat1.LOG_DATETIME IS NULL)
UNION
select dat2.*,dat2.log_datetime ActivityDate
from
TBLIRGLOG_TRANSACTION_DATA dat2
inner join
(SELECT *
FROM (
SELECT
rollnumber,
ec,
status,
internalStatus,
log_datetime,
ROW_NUMBER() OVER (ORDER BY log_datetime DESC) AS rn
FROM TBLIRGLOG_TRANSACTION_DATA
WHERE
log_datetime < inStartDate
AND (rollnumber = NVL(inRollNumber, rollnumber) OR NVL(inRollNumber, rollnumber) IS NULL)
)
WHERE rn = 1) dat3
on
dat2.rollnumber = dat3.rollnumber
and dat2.ec = dat3.ec and
dat2.status = dat3.status and
dat2.log_datetime = dat3.log_datetime
where
dat2.status= instatus
AND (DAT2.INTERNALSTATUS IN ('Admit','Enroll'))
)Result
left outer join TBLGUIUSER UT on
Result.USERID = UT.USER_ID
where (Result.rollnumber=nvl(inRollNumber,Result.rollnumber) --OR Result.rollnumber is null
)
and( Result.ec=nvl(inEC,Result.ec) OR Result.ec IS NULL)
and (Result.USERID =nvl(inUserID,Result.USERID) OR Result.USERID IS NULL)
--and (Result.ActivityDate >= nvl(inStartDate,Result.ActivityDate) OR Result.ActivityDate IS NULL)
and (Result.ActivityDate <= nvl(inEndDate,Result.ActivityDate) OR Result.ActivityDate IS NULL)
ORDER BY
UniqueId,Result.ActivityDate ASC;
end spGetReportData;
我想要检索开始日期和结束日期之间的数据,包括 Oracle SQL 中存在的每行数据的开始日期的前一行。
如果您有一个包含数据的最小示例:
CREATE TABLE table_name ( id, counter, dt ) AS
SELECT 1, LEVEL, DATE '2024-03-01' + LEVEL - 1 FROM DUAL CONNECT BY LEVEL <= 5
UNION ALL
SELECT 2, LEVEL, DATE '2024-03-02' + 2*(LEVEL - 1) FROM DUAL CONNECT BY LEVEL <= 3
UNION ALL
SELECT 3, 1, DATE '1970-01-01' FROM DUAL
UNION ALL
SELECT 3, 2, DATE '2024-03-03' FROM DUAL;
并且您想要查找每个
id
的开始日期和结束日期之间的行 2024-03-03 00:00:00
和 2024-03-04 23:59:59
以及每个 id
的单个最新前一行,那么您可以使用 LEAD
分析以获取下一行的日期并查找与该范围内的当前日期或下一个日期匹配的行:
SELECT id,
counter,
dt
FROM (
SELECT id,
counter,
dt,
LEAD(dt) OVER (PARTITION BY id ORDER BY dt) AS next_dt
FROM table_name
)
WHERE ( dt >= DATE '2024-03-03' AND dt < DATE '2024-03-05' )
OR ( next_dt >= DATE '2024-03-03' AND next_dt < DATE '2024-03-05' )
哪个输出:
身份证 | 柜台 | DT |
---|---|---|
1 | 2 | 2024-03-02 00:00:00 |
1 | 3 | 2024-03-03 00:00:00 |
1 | 4 | 2024-03-04 00:00:00 |
2 | 1 | 2024-03-02 00:00:00 |
2 | 2 | 2024-03-04 00:00:00 |
3 | 1 | 1970-01-01 00:00:00 |
3 | 2 | 2024-03-03 00:00:00 |