【问题标题】:PostgreSQL join to most recent record between tablesPostgreSQL 加入表之间的最新记录
【发布时间】:2012-01-06 18:19:21
【问题描述】:

我有两张表与这个问题有关:conversations 有很多 messages。基本结构(仅包含相关列)如下:

conversations (
  int id (PK)
)

create table conversation_participants (
  int id (PK),
  int conversation_id (FK conversations),
  int user_id (FK users),
  unique key on [conversation_id, profile_id]
)

create table messages (
  int id (PK),
  int conversation_id (FK conversations),
  int sender_id (FK users),
  int recipient_id (FK users),
  text body
)

对于每个对话条目,给定一个我想要接收的user_id

  • 用户参与的所有对话(即:conversations.*
  • 加入了最新的匹配消息(即:order by messages.id desc limit 1
  • 会话按其最近的消息 ID 排序(即:按messages.id desc 排序)

不幸的是,我可以找到的所有查询帮助似乎都与 MySQL 相关,而这在 PostgreSQL 中不起作用。我找到的最接近的是this answer on StackOverflow,它给出了select distinct on (...) 语法的示例。但是,除非我只是做错了,否则鉴于我需要使用该方法的分组约束,我似乎无法以正确的方式排序结果。

【问题讨论】:

    标签: postgresql join left-join


    【解决方案1】:

    所有信息都在“消息”表中,您不需要其他表:

    SELECT 
        id, 
        body,
        c.* -- content from conversations 
    FROM messages 
        JOIN
            (SELECT MAX(id) AS id, conversation_id 
            FROM messages 
            WHERE 1 IN(sender_id, recipient_id) -- the number is the userid, should be dynamic
            GROUP BY conversation_id) sub
            USING(id, conversation_id)
        JOIN conversations c ON c.id = messages.conversation_id
    ORDER BY
        id DESC;
    

    编辑:只需加入“对话”即可从此表中获取所需的数据。

    【讨论】:

    • conversations 表中实际上还有我需要的其他信息。在我的帖子开头,我试图说我只包含了与连接相关的表/列,但这可能会让人感到困惑,因为我不清楚我将选择的数据多于显示在这里。不幸的是,这种方法对我不起作用。
    • 检查新查询,它也加入了“转化”。
    【解决方案2】:

    试试这个:

    select
        *
    from
        conversation_participants cp
    
        join conversations c on
        c.id = cp.conversation_id
    
        -- assuming you only want the conversations where a
        -- message has been left. otherwise use left join
        join messages m on
        m.conversation_id = cp.conversation_id
        and m.id = (
                select
                        id
                from
                        messages _m
                where
                        _m.conversation_id = m.conversation_id
                        and sender_id = 1
                order by
                        id desc
                limit 1
        )
    where
            cp.user_id = 1
    order by
            m.id desc;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-11
      • 1970-01-01
      • 2010-10-27
      • 1970-01-01
      • 1970-01-01
      • 2011-03-07
      • 2019-09-12
      • 1970-01-01
      相关资源
      最近更新 更多