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