Sql 如何在不同表中的条目之后找到表中的下一个条目?
我想我只是遇到了一个问题,我不能把我的大脑集中在这个问题上,但我也不确定这是否真的可能 我有两张桌子。一个是事务日志。另一个是项目历史记录。我需要知道在设置项目进程状态时是否发生了事务,这样我就可以计算未设置该属性的所有事务 表中相关列的简化视图: 交易:Sql 如何在不同表中的条目之后找到表中的下一个条目?,sql,oracle,Sql,Oracle,我想我只是遇到了一个问题,我不能把我的大脑集中在这个问题上,但我也不确定这是否真的可能 我有两张桌子。一个是事务日志。另一个是项目历史记录。我需要知道在设置项目进程状态时是否发生了事务,这样我就可以计算未设置该属性的所有事务 表中相关列的简化视图: 交易: event_id event_type event_item_id event_timestamp 项目历史记录: item_id item_process_status item_history_timestamp 我需要做的是统计'7
event_id
event_type
event_item_id
event_timestamp
项目历史记录:
item_id
item_process_status
item_history_timestamp
我需要做的是统计'71',72',74个事件中的所有事件类型,其中事件\u项\u id的下一个条目,即项目\u历史\u时间戳是事件\u时间戳没有项目\u进程\u状态之后项目\u id的第一个项目\u历史条目。我想我应该使用LEAD、OVER或其他一些分析函数,但我对分析函数还不够熟悉,不知道如何构造这样的查询。过去我唯一一次使用它们是在一张桌子上
示例架构:
CREATE TABLE item (
item_id VARCHAR(5),
item_process_status VARCHAR(2)
CREATE TABLE item_history (
item_id VARCHAR(5),
item_process_status VARCHAR(2),
item_history_timestamp TIMESTAMP
);
CREATE TABLE event (
event_id VARCHAR(5),
event_type VARCHAR(2),
event_item_id VARCHAR(5),
event_timestamp TIMESTAMP
);
INSERT INTO item VALUES('10233', 'IP');
INSERT INTO item VALUES('40421', NULL);
INSERT INTO item VALUES('44026', NULL);
INSERT INTO item VALUES('55329', NULL);
INSERT INTO item_history VALUES('55329', NULL, TO_TIMESTAMP('2013-10-02 13:37', 'YYYY-MM-DD HH24:MI'));
INSERT INTO item_history VALUES('40421', NULL, TO_TIMESTAMP('2013-10-02 15:44', 'YYYY-MM-DD HH24:MI'));
INSERT INTO item_history VALUES('10233', 'OR', TO_TIMESTAMP('2013-10-03 08:21', 'YYYY-MM-DD HH24:MI'));
INSERT INTO item_history VALUES('10233', 'IP', TO_TIMESTAMP('2013-10-03 09:15', 'YYYY-MM-DD HH24:MI'));
INSERT INTO item_history VALUES('44026', NULL, TO_TIMESTAMP('2013-10-04 16:28', 'YYYY-MM-DD HH24:MI'));
INSERT INTO item_history VALUES('44026', 'IP', TO_TIMESTAMP('2013-10-05 11:56', 'YYYY-MM-DD HH24:MI'));
INSERT INTO item_history VALUES('40421', NULL, TO_TIMESTAMP('2013-10-06 10:03', 'YYYY-MM-DD HH24:MI'));
INSERT INTO item_history VALUES('10233', NULL, TO_TIMESTAMP('2013-10-06 14:19', 'YYYY-MM-DD HH24:MI'));
INSERT INTO item_history VALUES('55329', 'IP', TO_TIMESTAMP('2013-10-07 08:36', 'YYYY-MM-DD HH24:MI'));
INSERT INTO item_history VALUES('10233', NULL, TO_TIMESTAMP('2013-10-08 12:52', 'YYYY-MM-DD HH24:MI'));
INSERT INTO item_history VALUES('44026', NULL, TO_TIMESTAMP('2013-10-09 11:56', 'YYYY-MM-DD HH24:MI'));
INSERT INTO event VALUES ('00001', '71', '55329', TO_TIMESTAMP('2013-10-02 13:44', 'YYYY-MM-DD HH24:MI'));
INSERT INTO event VALUES ('00002', '69', '40421', TO_TIMESTAMP('2013-10-03 17:23', 'YYYY-MM-DD HH24:MI'));
INSERT INTO event VALUES ('00003', '43', '10233', TO_TIMESTAMP('2013-10-03 22:56', 'YYYY-MM-DD HH24:MI'));
INSERT INTO event VALUES ('00004', '52', '44026', TO_TIMESTAMP('2013-10-04 19:12', 'YYYY-MM-DD HH24:MI'));
INSERT INTO event VALUES ('00005', '72', '10233', TO_TIMESTAMP('2013-10-04 20:32', 'YYYY-MM-DD HH24:MI'));
INSERT INTO event VALUES ('00006', '74', '40421', TO_TIMESTAMP('2013-10-05 17:06', 'YYYY-MM-DD HH24:MI'));
INSERT INTO event VALUES ('00007', '71', '44026', TO_TIMESTAMP('2013-10-06 11:09', 'YYYY-MM-DD HH24:MI'));
INSERT INTO event VALUES ('00008', '80', '10233', TO_TIMESTAMP('2013-10-06 16:29', 'YYYY-MM-DD HH24:MI'));
INSERT INTO event VALUES ('00009', '71', '55329', TO_TIMESTAMP('2013-10-07 13:44', 'YYYY-MM-DD HH24:MI'));
INSERT INTO event VALUES ('00010', '69', '40421', TO_TIMESTAMP('2013-10-07 17:23', 'YYYY-MM-DD HH24:MI'));
INSERT INTO event VALUES ('00011', '43', '10233', TO_TIMESTAMP('2013-10-07 22:56', 'YYYY-MM-DD HH24:MI'));
INSERT INTO event VALUES ('00012', '52', '44026', TO_TIMESTAMP('2013-10-08 19:12', 'YYYY-MM-DD HH24:MI'));
INSERT INTO event VALUES ('00013', '72', '10233', TO_TIMESTAMP('2013-10-08 20:32', 'YYYY-MM-DD HH24:MI'));
INSERT INTO event VALUES ('00014', '74', '40421', TO_TIMESTAMP('2013-10-09 17:06', 'YYYY-MM-DD HH24:MI'));
预期查询输出:
事件| id |计数*
71 | 2
72 | 1
74 | 2
这里的技巧是,前71个事件00001不被计算,因为项目55329在下一个项目历史记录条目中具有流程状态,而事件00013不被计算,因为项目当前具有流程状态,并且它发生在项目10233的最后一个事务之后
请注意,这不适用于SQLfiddle,因为站点显然没有TO_时间戳功能。首先,为项目构建完整的状态历史记录:
select
item_id,
(
lag(until_time) over (
partition by item_id
order by until_time
)
) since_time,
until_time,
item_process_status
from (
select
item_id,
item_history_timestamp until_time,
item_process_status
from
item_history
union all
select
item_id,
systimestamp until_time,
item_process_status
from item
)
然后将其与事件历史记录连接,以获取状态历史记录的每个片段发生的事务,并应用过滤器:
select
full_history.item_id,
full_history.since_time,
full_history.until_time,
full_history.item_process_status,
item_events.event_type,
item_events.event_timestamp,
item_events.event_id
from
(
select
item_id,
(
lag(until_time) over (
partition by item_id
order by until_time
)
) since_time,
until_time,
item_process_status
from (
select
item_id,
item_history_timestamp until_time,
item_process_status
from
item_history
union all
select
item_id,
systimestamp until_time,
item_process_status
from
item
)
)
full_history,
event item_events
where
item_events.event_item_id = full_history.item_id
and
item_events.event_timestamp < full_history.until_time
and
(
item_events.event_timestamp >= full_history.since_time
or
(full_history.since_time is null)
)
and
item_events.event_type in ('71','72','74')
and
(full_history.item_process_status is null)
首先,为项目构建完整的状态历史记录:
select
item_id,
(
lag(until_time) over (
partition by item_id
order by until_time
)
) since_time,
until_time,
item_process_status
from (
select
item_id,
item_history_timestamp until_time,
item_process_status
from
item_history
union all
select
item_id,
systimestamp until_time,
item_process_status
from item
)
然后将其与事件历史记录连接,以获取状态历史记录的每个片段发生的事务,并应用过滤器:
select
full_history.item_id,
full_history.since_time,
full_history.until_time,
full_history.item_process_status,
item_events.event_type,
item_events.event_timestamp,
item_events.event_id
from
(
select
item_id,
(
lag(until_time) over (
partition by item_id
order by until_time
)
) since_time,
until_time,
item_process_status
from (
select
item_id,
item_history_timestamp until_time,
item_process_status
from
item_history
union all
select
item_id,
systimestamp until_time,
item_process_status
from
item
)
)
full_history,
event item_events
where
item_events.event_item_id = full_history.item_id
and
item_events.event_timestamp < full_history.until_time
and
(
item_events.event_timestamp >= full_history.since_time
or
(full_history.since_time is null)
)
and
item_events.event_type in ('71','72','74')
and
(full_history.item_process_status is null)
请提供样本数据和预期输出,在SQLFiddle上提供示例数据和预期输出的另一个好处是,当你把所有这些都放进去的时候,你已经掌握了自己解决问题所需的一切——在这种情况下,你可以发布自己问题的答案并接受它——你可能会获得一些解决问题的选票你自己。:-分享和享受。确实如此:我想你忘了在SQLFiddle从默认的MySQL改为Oracle。请提供示例数据和预期输出,在SQLFiddle上提供示例数据和预期输出的另一个好处是,当你把所有这些都放进去的时候,你已经掌握了自己解决问题所需的一切——在这种情况下,你可以发布自己问题的答案并接受它——你可能会获得一些解决问题的选票你自己。:-分享和享受。确实如此:我想你忘了在SQLFiddle.Yikes上从默认的MySQL改为Oracle吧!这就成功了。事实上,我又加了一个包装纸,把它加入到每月的总数中,但这并没有改变多少。哎呀!这就成功了。实际上,我添加了另一个包装器,将其计入每月总数,但这并没有改变多少。