如果有重复且更复杂,则显示第一行

时间:2018-11-07 07:35:56

标签: sql postgresql

chat_transcript
id | transcript_id | date 
1  | 123           | 2018-11-04 
2  | 234           | 2018-11-05
3  | 345           | 2018-11-06

chat_message
id | transcript_id | text | author
1  | 123           | a    | null
2  | 123           | b    | Tom
3  | 123           | c    | Paul
4  | 234           | d    | null
5  | 345           | e    | Bryan
6  | 345           | f    | Bryan

我想要这样的结果

id | transcript_id | date       | text | author
1  | 123           | 2018-11-04 | a    | Tom
2  | 234           | 2018-11-05 | d    | null
3  | 345           | 2018-11-06 | e    | Bryan

我想通过transcript_id将chat_transcript和chat_message一起加入, 当用户发送第一个chat_message消息时,作者将为空,直到代理发送消息为止。但我想为此聊天创建一个API。我主要想抓住每个聊天的第一行(每个聊天都有相同的transcript_id)。 我想获取id = 1、4、5、6。

我知道我可以做

select distinct on (m.transcript_id)
  *
from chat_transcript as t
join chat_message as m on t.id = m.transcript_id

但是这是复杂的部分,如果作者为空,我想看看其他具有价值的行。如果有值,我想用空值替换该值

我找到了一种工作方法,但是我仍然感觉不太干净。

select distinct on (n.transcript_id)
    t.id, t.date, n.transcript_id, n.text, n.author
form chat_transcript as t
join (
    select
        m.id, m.transcript_id, m.text, a.author
    from chat_message as m
    join (
        select
            t.id, string_agg(distinct m.author, ', ') as author
        from chat_transcript as t
        join chat_message as m on t.id = m.transcript_id
        group by t.id
    ) as a on m.transcript_id = a.id
 ) as n on t.id = n.transcript_id

小清理版本

select distinct on (m.transcript_id)
    nt.id, nt.date, m.index, m.text, nt.author
from chat_message as m
join (
    select
        t.id, t.date, string_agg(distinct m.author, ', ') as author
    from chat_transcript as t
    join chat_message as m on t.id = m.transcript_id
    group by t.id
) as nt on m.transcript_id = nt.id

1 个答案:

答案 0 :(得分:0)

如果您希望每个成绩单的第一条消息,可以使用distinct on

select distinct on (t.transcript_id) . . .
from chat_transcript t join
     chat_message m
     on t.transcript_id = m.transcript_id
order by t.transcript_id, m.id;