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

时间:2016-01-06 13:23:09

标签: oracle sql-view

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

我简单地说SQL只显示了相应的部分,你可以在这个SQL-fiddle中看到它,但是为了保护链接不受破坏的链接

messages

message_nr | user | value

messageStatus

id | message_nr | status | status_recieved_at

我试图实现的是一个视图,其中将计算前一条消息的已定义message_nr。上一条消息的定义与要计算的消息的user相同,status_recieved_at的最大status_recieved_at。只有"已完成"的消息状态(在此示例中为3)可以是a并且有先前的消息。

因此视图的预期结果为

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

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

为达到此目的,我写了以下选择语句

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的消息,而不仅仅是最大值为1的行。 SQLfiddle的输出也与我预期的大不相同。

我虽然可以使用rownum <= 1来减少数量,但我不知道如何为每封邮件重复它,因为我不想将总结果减少到只有一行

编辑:我也为SELECT-part尝试了这个语句:

    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用于在Stackoverflow上发布!

1 个答案:

答案 0 :(得分:1)

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;