【问题标题】:chat table summary list pgsql聊天表摘要列表 pgsql
【发布时间】:2020-07-15 08:51:32
【问题描述】:

我有如下聊天记录表。我将在哪里存储用户 ID。

我正在使用 Postgresql

CREATE TABLE chat_history (
    chat_id serial,
    sender_id serial REFERENCES users(user_id) ON DELETE CASCADE,
    recipient_id serial REFERENCES users(user_id) ON DELETE CASCADE,
    message text NOT NULL,
    created_on TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    channel_id VARCHAR(100),
    PRIMARY key (chat_id),
    read_flag boolean
);

现在我想获取用户聊天的摘要列表。 例如:user1 - senderId = 1,user2 - recipientId = 2。

  1. 如果这两个用户正在聊天,我需要提取历史记录。如何拉取用户的历史记录

  2. 如果一个用户有多个用户的未读消息如何获取摘要列表 喜欢:

  3. user1 到 user2 => 5 条未读消息

  4. user3 到 user2 => 2 条未读消息

  5. user5 到 user2 => 2 条未读消息

我已经尝试过以下查询

select  sender_id, recipient_id, count(*) from chat_history ch 
where (sender_id = 99 or recipient_id = 99) and (sender_id = 98 or recipient_id = 98)
and read_flag = false or read_flag = null
group by (sender_id, recipient_id, read_flag);

输出:

但它应该返回 count = 4 而与发件人和收件人 ID 无关

编辑: 尝试以下查询

select distinct sender_id, recipient_id, count(*) from chat_history ch 
where (sender_id = 99 or recipient_id = 99) 
and read_flag = false or read_flag = null
group by (read_flag, sender_id, recipient_id);

但结果相同

添加现场操场:https://www.db-fiddle.com/f/4xvD4ZTPW2npKcy3Au92Y9/4

【问题讨论】:

  • 嘿,您的 CREATE-Statement 与您的查询不匹配,它错过了 read_flag 列。最重要的是要重现您的问题,需要用户表和一些示例数据来证明您的问题。顺便说一句:检查查询的 read_flag = null 部分,这总是会产生 FALSE。如果在 SQL 中检查 null 使用 is NULL
  • AlexFunk,感谢您的意见。我在问题中添加了 read_flag。让我知道是否有任何在线环境可以让我添加少量数据并进行查询。
  • 如果您使用 Postgres,为什么要使用 oracleplsqlplsqldeveloper 标签?这些技术与 Postgres 无关。 Postgres 使用 PL/pgSQL 来编写存储过程和函数,而不是 PL/SQL。请不要为完全不相关的事物添加标签
  • @a_horse_with_no_name,都是关于查询的。如果任何其他开发人员遇到这个问题,他们可以帮助我,所以我添加了这些标签。
  • sql 标签就足够了。

标签: sql postgresql


【解决方案1】:

您的 db-fiddle 和您的问题描述不匹配。你在这里要求几个不同的东西。

查询 #1 解决了您问题中的示例

    with all_ids as (
      select sender_id as user_id from chat_history
      union
      select recipient_id from chat_history
    )
    select i.user_id, count(*) as unread_sent_or_rcvd
      from chat_history h
      join all_ids i 
        on (i.user_id = h.sender_id or i.user_id = h.recipient_id)
     where coalesce(h.read_flag, false) = false
     group by i.user_id
     order by i.user_id;

| user_id | unread_sent_or_rcvd |
| ------- | ------------------- |
| 97      | 1                   |
| 98      | 48                  |
| 99      | 46                  |

查询 #2 解决了您的问题陈述

我查了一下,在他的数据中有一条98的记录,里面有一条给自己的未读消息。他利用平等的机会跟踪到了一个新的水平。

    with all_ids as (
      select sender_id as user_id from chat_history
      union
      select recipient_id from chat_history
    )
    select i.user_id,
           case
              when i.user_id = h.sender_id then h.recipient_id
              else h.sender_id
           end as correspondent_id,
           count(*) filter (where i.user_id = h.sender_id) as unread_sent,
           count(*) filter (where i.user_id = h.recipient_id) as unread_rcvd
      from chat_history h
      join all_ids i 
        on (i.user_id = h.sender_id or i.user_id = h.recipient_id)
     where coalesce(h.read_flag, false) = false
     group by i.user_id, 
              case
                when i.user_id = h.sender_id then h.recipient_id
                else h.sender_id
              end
     order by i.user_id;

| user_id | correspondent_id | unread_sent | unread_rcvd |
| ------- | ---------------- | ----------- | ----------- |
| 97      | 98               | 1           | 0           |
| 98      | 97               | 0           | 1           |
| 98      | 98               | 1           | 1           |
| 98      | 99               | 44          | 2           |
| 99      | 98               | 2           | 44          |

View on DB Fiddle

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-07
    • 2013-08-09
    • 1970-01-01
    • 1970-01-01
    • 2012-04-28
    • 1970-01-01
    • 1970-01-01
    • 2023-02-14
    相关资源
    最近更新 更多