创建视图以计算之前的消息

Creating view to calculate a previous message

我正在尝试构建一个视图,为我显示每条消息的上一条消息。

我将 SQL 简单化为仅显示相应的部分,您可以在此 SQL-fiddle 中看到它,但为了避免损坏的链接,这里是架构

table messages:

message_nr | user | value

table messageStatus:

id | message_nr | status | status_recieved_at

我试图实现的是一个视图,其中将针对已定义的 message_nr 计算上一条消息。前一条消息由相同的 user 定义,并且最大值 status_recieved_at 低于要为其计算的消息的 status_recieved_at。只有状态为 "finished" 的消息(在本例中为 3)才可能是 a 并且有上一条消息。

因此视图的预期结果将是

+---------+-----------------+
| message | previousMessage |
+---------+-----------------+
|       1 | NULL            |
|       2 | 1               |
|       3 | NULL            |
|       5 | 3               |
|       6 | 2               |
|       7 | NULL            |
+---------+-----------------+

消息 4 不在 table 中,因为它从未达到最终状态。

为了达到这个目的,我写了下面的 select 语句

create view whatsThePreviousMessage as (

    select m.message_nr as message, p.message_nr as previousMessage
    from messages m
    join messageStatus msm on (msm.message_nr = m.message_nr and msm.status = 3)
    left join messages p on (p.user = m.user)
    join messageStatus msp on (msp.message_nr = p.message_nr and msp.status = 3)

    where msp.status_recieved_at < msm.status_recieved_at
    order by msp.status_recieved_at desc
)

如您所料,这为我提供了具有较低 status_recieved_at 的所有消息,而不仅仅是具有最大值的行。 SQLfiddle 的输出也与我预期的大不相同。

虽然我可以通过使用 rownum <= 1 来减少数量,但我不知道如何为每条消息减少它,因为我不想将总结果减少到只有一行。

编辑:我也为 SELECT 部分尝试了此语句:

    select m.message_nr as message, p.message_nr as previousMessage, msm.status_recieved_at as mDate, msp.status_recieved_at as pDate
    from messages m
    join messageStatus msm on (msm.message_nr = m.message_nr and msm.status = 3)

    left join messages p on (p.user = m.user)
    join messageStatus msp on (msp.message_nr = p.message_nr and msp.status = 3)
    where msp.status_recieved_at = ( select max(ms3.status_recieved_at)  from messageStatus ms3 join messages m3 on (m3.message_nr = ms3.message_nr and ms3.status = 3 and m.user = m3.user) where ms3.status_recieved_at < msm.status_recieved_at)
    or msp.status_recieved_at is null

但这不包括结果中没有先前消息的消息。此外,SQLfiddle 无法执行它,而我的 H2 数据库可以。 注意 我需要 Oracle 的工作解决方案。 H2 仅用于本地测试,SQLfiddle 用于在 Whosebug 上发布!

select
    messages.message_nr message,
    lag(messages.message_nr) over (partition by messages."USER" order by messagestatus.status_recieved_at) previousmessage
from
    messages
    join messagestatus on messages.message_nr = messagestatus.message_nr and messagestatus.status = 3
order by
    messages.message_nr;