与SQL搏斗

与SQL搏斗,sql,mysql,Sql,Mysql,我在MySQL数据库中有这个: table Message sender_id int recipient_id int created datetime [title, body, etc... omitted] 在单个查询中,是否可以从该列表中获得与id为N的给定用户通信的所有用户的列表(意思是N出现在发送者id或接收者id),按创建的排序,包括创建的的最新值,无重复(没有发送方/接收方对N、M和M、N) 我很确定答案是否定的,但我很难说服自己。下午精神迟钝

我在MySQL数据库中有这个:

table Message
    sender_id int
    recipient_id int
    created datetime
    [title, body, etc... omitted]
在单个查询中,是否可以从该列表中获得与id为N的给定用户通信的所有用户的列表(意思是N出现在
发送者id
接收者id
),按
创建的
排序,包括
创建的
的最新值,无重复(没有发送方/接收方对N、M和M、N)

我很确定答案是否定的,但我很难说服自己。下午精神迟钝

如果没有,你会推荐什么最有效的替代方案



编辑:天哪,堆栈溢出最近在跳跃。在我意识到我忘记指定我希望创建的
的最新值与每行中的其他用户ID一起出现之前,有8个答案。

不,这很简单

SELECT DISTINCT IF(sender_id=4, recipient_id, sender_id) AS partner_id
FROM message
WHERE sender_id=4 OR recipient_id=4

很明显,你很难说服自己,否则你就不会问。我很确定答案是肯定的。但是,如果不了解底层数据的一些特殊性,就很难找到正确的解决方案

它可能是朝着

select 
  sender_id,
  recipient_id
from
  message
where
 (sender_id    = n or 
  recipient_id = n   )
order by
  created desc
试试这个

SELECT distinct recipient_id
FROM Message
WHERE sender_id = @id

UNION

SELECT distinct sender_id
FROM Message
WHERE recipient_id = @id
union子句将删除两个查询中的重复项。实际上,查看它,您也不需要distinct,因为union也会为您这样做(有没有人知道使用distinct预筛选子句或让union处理所有重复项更有效?

使用:

SELECT x.friend,
       MAX(x.created)
  FROM (SELECT t.recipient_id 'friend',
               t.created
          FROM MESSAGE t
         WHERE t.sender_id = @id 
        UNION
        SELECT r.sender_id 'friend',
               r.created
          FROM MESSAGE r
         WHERE r.recipient_id = @id) x
GROUP BY x.friend

我认为这将最符合您的要求:

SELECT *
FROM user
WHERE 
  user_id in 
    (select recipient_id FROM message m where m.sender_id = X)
  OR user_id in
    (select sender_id FROM message m where m.recipient_id = X)
order by
  created DESC
没有重复,没有联合,也没有特定于SQL方言的东西。

这是我的:)

就是这样:

  • 没有副本
  • 按创建的描述排序

除了“无发送者/接收者对”重复部分,“M”在您的需求中代表什么?你是说你不想要自引用吗?M是另一个用户的ID。最后我想要的是一个M及其关联的最近创建时间的列表。这样你就不需要联合。显然,你必须用你的用户ID替换4。啊,这很接近。不幸的是,我不清楚,而且我还需要时间戳本身,我想它会破坏distinct?为什么它会破坏distinct?不过还有一件事:distinct通常非常慢。通常分组速度更快,但我不确定在这种情况下如何应用。也许其他人可以帮上忙……因为如果我“选择distinct if(发送者id=4,接收者id,发送者id)作为合作伙伴id,created”,那么我自己会得到重复的合作伙伴id,我只需要创建一个视图,然后用它连接到表中的任何其他字段,我想UNION可能会更快,因为distinct非常慢。而且,仅使用DISTINCT仍允许重复,当通过发送和接收与另一个人进行通信时……如果要使用
UNION
,则不需要使用
DISTINCT
——如果要使用
UNION ALL
,则不需要使用
UNION ALL
。除非涉及数万行,否则不会对效率造成很大影响,也不会查看数据可在其他地方使用的独特ID是模块化的,易于理解。事实上,我们被要求包括每个用户最近创建的日期=>您必须包括group by子句:)我刚从您的原始帖子中写完我自己的版本,但我删除了它,因为您应该得到积分
select id, max(created) as lastMessage
(
    select sender_id as id, created
    from Message
    union
    select recipient_id as id, created
    from Message
) as MergedMessage
where id = ?id
group by id
order by max(created) desc