在oracle中基于同一列中的一系列条件进行查询

在oracle中基于同一列中的一系列条件进行查询,oracle,Oracle,基本上,我有一个表来存储一个项目的所有状态变化(即1->2->9->6->0)。每个更改都由用户提交。每次状态更改时,时间戳、用户名和新状态都存储为单独的行。任务是获取状态由特定用户从6更改为9的项目的所有ID。状态从6更改为9总是在同一天发生 目前我正在使用以下查询: select t1.id, t1.date, t1.id_status from (select * table1 where id_status = 9 and (user =

基本上,我有一个表来存储一个项目的所有状态变化(即1->2->9->6->0)。每个更改都由用户提交。每次状态更改时,时间戳、用户名和新状态都存储为单独的行。任务是获取状态由特定用户从6更改为9的项目的所有ID。状态从6更改为9总是在同一天发生

目前我正在使用以下查询:

select t1.id, t1.date, t1.id_status
from (select * table1 
            where id_status = 9
            and (user = 'user1' or user = 'user2')
            and table1.date > sysdate - interval '12' month) t1
join (select * from table1 
        where id_status = 6
        and table1.date > sysdate - interval '12' month) t2
on t1.id = t2.id 
and to_char(t1.date, 'dd.mm.yyyy') = to_char(t2.date, 'dd.mm.yyyy')
and t1.date > t2.date
有什么方法可以改进它吗?

您可以尝试使用或函数

这就是你要找的吗

WITH tab AS(
SELECT 1 AS ID, 0 AS status FROM dual UNION ALL
SELECT 2 AS ID, 6 AS status FROM dual UNION ALL
SELECT 3 AS ID, 0 AS status FROM dual UNION ALL
SELECT 4 AS ID, 6 AS status FROM dual UNION ALL
SELECT 5 AS ID, 9 AS status FROM dual UNION ALL
SELECT 6 AS ID, 1 AS status FROM dual UNION ALL
SELECT 7 AS ID, 2 AS status FROM dual UNION ALL
SELECT 8 AS ID, 9 AS status FROM dual UNION ALL
SELECT 9 AS ID, 6 AS status FROM dual UNION ALL
SELECT 10 AS ID, 9 AS status FROM dual 
)
SELECT * FROM (
  SELECT  t.ID
  ,t.status
  ,LEAD(t.status, 1, 0) OVER (ORDER BY t.id) AS next_status
  ,LEAD(t.id, 1, 0) OVER (ORDER BY t.id) AS next_id
  FROM tab t

) x
WHERE x.status = 6 AND x.next_status = 9

结果:

ID |状态|下一个状态|下一个ID -: | -----: | ----------: | ------: 4 | 6 | 9 | 5 9 | 6 | 9 | 10
dbfiddle

您可以使用
行数
窗口功能和
自连接
,如下所示:

SQL> WITH tab AS(
  2  SELECT 1 AS ID, 0 AS status FROM dual UNION ALL
  3  SELECT 2 AS ID, 6 AS status FROM dual UNION ALL
  4  SELECT 3 AS ID, 0 AS status FROM dual UNION ALL
  5  SELECT 4 AS ID, 6 AS status FROM dual UNION ALL
  6  SELECT 5 AS ID, 9 AS status FROM dual UNION ALL
  7  SELECT 6 AS ID, 1 AS status FROM dual UNION ALL
  8  SELECT 7 AS ID, 2 AS status FROM dual UNION ALL
  9  SELECT 8 AS ID, 9 AS status FROM dual UNION ALL
 10  SELECT 9 AS ID, 6 AS status FROM dual UNION ALL
 11  SELECT 10 AS ID, 9 AS status FROM dual
 12  ),
 13  -- your query starts from here
 14  cte as (
 15  select id, status, row_number() over (order by id) as rn from tab
 16  )
 17  select t.id, t.status, t1.id next_id, t1.status next_status
 18    from cte t join cte t1 on t.rn + 1 = t1.rn
 19   where t.status = 6 and t1.status = 9
 20   order by t.id;

        ID     STATUS    NEXT_ID NEXT_STATUS
---------- ---------- ---------- -----------
         4          6          5           9
         9          6         10           9

SQL>

多亏了示例数据的修补程序。

请显示这两个表的结构。例如,只有一个表,假设它只有4行:id--date--user--id_status
一个状态从6更改为9的项…
——换句话说,这基本上意味着:按顺序查找给定项(id)的两个相邻记录“时间戳“列,其中第一条记录的状态为6,下一条记录的状态为9,对吗?如果我们谈论的是一个确切的ID,是的,它的相邻记录在ID_status行中应该是6和9。但是在一个给定的表中,由于其他ID有自己的记录,这些记录可以相隔10行或更多行。理论上应该可以工作,但我的表包含超过100k行,因此不可行。100k不是一个大数字,为什么不可行?
SQL> WITH tab AS(
  2  SELECT 1 AS ID, 0 AS status FROM dual UNION ALL
  3  SELECT 2 AS ID, 6 AS status FROM dual UNION ALL
  4  SELECT 3 AS ID, 0 AS status FROM dual UNION ALL
  5  SELECT 4 AS ID, 6 AS status FROM dual UNION ALL
  6  SELECT 5 AS ID, 9 AS status FROM dual UNION ALL
  7  SELECT 6 AS ID, 1 AS status FROM dual UNION ALL
  8  SELECT 7 AS ID, 2 AS status FROM dual UNION ALL
  9  SELECT 8 AS ID, 9 AS status FROM dual UNION ALL
 10  SELECT 9 AS ID, 6 AS status FROM dual UNION ALL
 11  SELECT 10 AS ID, 9 AS status FROM dual
 12  ),
 13  -- your query starts from here
 14  cte as (
 15  select id, status, row_number() over (order by id) as rn from tab
 16  )
 17  select t.id, t.status, t1.id next_id, t1.status next_status
 18    from cte t join cte t1 on t.rn + 1 = t1.rn
 19   where t.status = 6 and t1.status = 9
 20   order by t.id;

        ID     STATUS    NEXT_ID NEXT_STATUS
---------- ---------- ---------- -----------
         4          6          5           9
         9          6         10           9

SQL>