我正在尝试构建一个视图,向我显示每条消息的上一条消息。
我简单地说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上发布!
答案 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;