如何获取唯一值以比较同一表的两列?

问题描述

当前,我正在使用sqlite进行Django项目,在其中创建消息聊天框,并希望获取登录用户的最新消息(无论发送还是接收)。

id   receiver_id      sender_id    message_content   created_at
1    1                 2            some text         2020-08-11 13:29:47.342944
3    3                 2            some text         2020-08-11 13:44:55.499638
4    2                 1            some text         2020-08-11 14:20:55.499638
5    1                 2            some text         2020-08-12 05:06:05.497500
6    2                 5            some text         2020-08-12 10:39:31.234082
7    4                 1            some text         2020-08-14 13:25:19.357876

使用下面的SQL查询之后。

SELECT max(created_at),* 
FROM hireo_messages 
WHERE receiver_id=2 or sender_id=2 
GROUP BY receiver_id,sender_id 
ORDER BY created_at DESC

我得到了以下结果。

id      receiver_id   sender_id     message_content   created_at
6       2             5             some text         2020-08-12 10:39:31.234082
5       1             2             some text         2020-08-12 05:06:05.497500
4       2             1             some text         2020-08-11 14:20:55.499638
3       3             2             some text         2020-08-11 13:44:55.499638

您会看到ID 5、4彼此聊天。因此,我想获取除ID 4以外的所有记录,因为2个用户间的最新聊天是在ID 5中。这与Facebook Messenger仪表板中使用的概念相同。 请指导我是通过查询解决还是以其他方式解决。预先感谢您的帮助!

解决方法

我想你想要

SELECT LEAST(receiver_id,sender_id),GREATEST(receiver_id,MAX(created_at)
FROM hireo_messages
WHERE 2 IN (receiver_id,sender_id)
GROUP BY LEAST(receiver_id,sender_id)
ORDER BY MAX(created_at) DESC;

如果需要完整的行,请使用窗口功能:

SELECT m.*
FROM (SELECT m.*,ROW_NUMBER() OVER (PARTITION BY LEAST(receiver_id,sender_id) ORDER BY created_at DESC) as seqnum
      FROM hireo_messages m
      WHERE 2 IN (receiver_id,sender_id)
     ) m
WHERE seqnum = 1
ORDER BY MAX(created_at) DESC;
,

您可以使用窗口功能MAX()

select id,receiver_id,sender_id,message_content,created_at 
from (
  select *,max(created_at) over (partition by min(receiver_id,max(receiver_id,sender_id)) last_date
  from hireo_messages
  where 2 in (receiver_id,sender_id) 
)
where created_at = last_date
order by id desc

如果您的SQLite版本不支持窗口功能,则可以使用NOT EXISTS

select h.* from hireo_messages h
where 2 in (receiver_id,sender_id)
and not exists (
  select 1 from hireo_messages
  where min(receiver_id,sender_id) = min(h.receiver_id,h.sender_id)
    and max(receiver_id,sender_id) = max(h.receiver_id,h.sender_id)
  and created_at > h.created_at
)  
order by h.id desc 

请参见demo
结果:

| id  | receiver_id | sender_id | message_content | created_at                 |
| --- | ----------- | --------- | --------------- | -------------------------- |
| 6   | 2           | 5         | some text       | 2020-08-12 10:39:31.234082 |
| 5   | 1           | 2         | some text       | 2020-08-12 05:06:05.497500 |
| 3   | 3           | 2         | some text       | 2020-08-11 13:44:55.499638 |