如何在 Oracle SQL 中检索开始日期的前一行以及开始到结束日期数据?

问题描述 投票:0回答:1

我想要检索开始日期和结束日期之间的数据,包括 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;
sql oracle stored-procedures
1个回答
0
投票

我想要检索开始日期和结束日期之间的数据,包括 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

小提琴

© www.soinside.com 2019 - 2024. All rights reserved.