我有一个数据表详细说明父表的行的动作序列,其中列ID是该外键.列SEQ是这些动作发生的顺序,ACTION是发生的动作.
ID SEQ ACTION
12345.00 2 SUSPEND
12345.00 3 CLEAR
12345.00 4 SUSPEND
12345.00 6 CLEAR
12345.00 7 SUSPEND
12345.00 8 RESUME
12345.00 9 SUSPEND
12345.00 10 RESUME
12345.00 11 CLEAR
Run Code Online (Sandbox Code Playgroud)
我试图以这样的方式呈现数据,以便我可以识别未清除的SUSPEND和RESUME操作.在这种情况下,我的结果将如下所示;
12345.00 7 SUSPEND 8 RESUME
12345.00 9 SUSPEND
Run Code Online (Sandbox Code Playgroud)
情况就是这样;
CLEAR行动3删除了SUSPEND行动2.
CLEAR行动6删除了SUSPEND行动4.
CLEAR动作9删除了RESUME动作8.
ACTION列可以在序列中包含其他操作,因此为了清楚起见,我已删除了这些操作.
如果CLEAR将继续执行操作,则清除该操作.
对不起,如果这令人困惑.我无法改变架构!
我试图简化这个问题;
ID SEQ ACTION
12345.00 2 SUSPEND
12345.00 3 RESUME
12345.00 4 CLEAR
12345.00 5 RESUME
12345.00 6 SUSPEND
Run Code Online (Sandbox Code Playgroud)
结果应该是这样的;
12345.00 2 SUSPEND 5 RESUME
12345.00 6 SUSPEND
Run Code Online (Sandbox Code Playgroud)
我尝试了几种方法,但我无法想象如何停止包含3号的RESUME.
尝试:
SELECT *
FROM (
SELECT t.*,
lead( SEQ ) over ( partition by id order by seq ) next_seq,
lead( action ) over ( partition by id order by seq ) next_action
FROM table1 T
)
WHERE action = 'SUSPEND'
AND next_action <> 'CLEAR'
Run Code Online (Sandbox Code Playgroud)
演示:http://sqlfiddle.com/#!4/5ea45/8
好的。现在,我从kordirko那里偷了小提琴,从simon那里偷了概念,然后用我的方式烹饪。
CREATE TABLE TABLE1
(
"ID" INT,
"SEQ" INT,
"ACTION" VARCHAR2 ( 7 )
);
INSERT ALL
INTO TABLE1 ( "ID", "SEQ", "ACTION" )
VALUES ( 12345.00, 2, 'SUSPEND' )
INTO TABLE1 ( "ID", "SEQ", "ACTION" )
VALUES ( 12345.00, 3, 'RESUME' )
INTO TABLE1 ( "ID", "SEQ", "ACTION" )
VALUES ( 12345.00, 4, 'CLEAR' )
INTO TABLE1 ( "ID", "SEQ", "ACTION" )
VALUES ( 12345.00, 5, 'RESUME' )
INTO TABLE1 ( "ID", "SEQ", "ACTION" )
VALUES ( 12345.00, 6, 'SUSPEND' )
SELECT * FROM DUAL;
Run Code Online (Sandbox Code Playgroud)
所以我从你的问题中了解到的是,它最初没有被正确解释。但第二个预期结果就达到了目的。(我可能还是错了)
WITH AFTER_CHECK
AS (SELECT T.ID,
T.SEQ,
T.ACTION,
CASE
WHEN ACTION = 'CLEAR'
THEN
1
WHEN LEAD ( ACTION ) OVER (PARTITION BY ID ORDER BY SEQ) =
'CLEAR'
THEN
1
ELSE
0
END
AS IGNORE_CURRENT
FROM TABLE1 T)
SELECT *
FROM (SELECT T.ID,
T.SEQ,
T.ACTION,
LEAD ( SEQ ) OVER (PARTITION BY ID ORDER BY SEQ) NEXT_SEQ,
LEAD ( ACTION ) OVER (PARTITION BY ID ORDER BY SEQ)
NEXT_ACTION
FROM AFTER_CHECK T
WHERE IGNORE_CURRENT = 0)
WHERE ACTION = 'SUSPEND';
Run Code Online (Sandbox Code Playgroud)
输出:
12345 2 SUSPEND 5 RESUME
12345 6 SUSPEND
Run Code Online (Sandbox Code Playgroud)
我所做的是分配一个标志来检查设置为忽略的连续操作,如果它们有一个名为 ACTIONCLEAR
或一个名为 NEXT ACTION 的操作CLEAR
。然后我使用 kordirko 的函数片段LEAD
通过所需操作的过滤器来完成这项工作。
在这里查看小提琴
归档时间: |
|
查看次数: |
182 次 |
最近记录: |