创建视图以计算之前的消息
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;
我正在尝试构建一个视图,为我显示每条消息的上一条消息。
我将 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;