SQL group by有两列

时间:2017-07-26 14:05:59

标签: mysql

我面临一个非常有趣的问题。希望你有答案。

首先看我的表结构

id  | sender |  receiver | msg
1   |   10   |    5      | hello
2       10        5         df
3       5        10         fds
4       10        7         sdf

现在我想只从发送者和接收者中选择不同的对(不是5,10或10,5因为两者都相同)

我正在使用SELECT * FROM消息WHERE sender=10 or reciever = 10 GROUP by sender,reciever但是这会返回10,5和5,10,但我只想要一个。 请帮忙

2 个答案:

答案 0 :(得分:2)

mySQL没有分析功能可以使这个非常直接;但我们可以模拟它们。我可以使用row_number(user1,user2分区),但在mysql中我们使用3个用户变量来模拟它。

最内层查询(别名A)定义了两个新列user1和user2。它确保user1始终小于user2,为我提供了对反转对进行分组的方法((10,5),(5,10))

然后使用在子查询中生成的user1和user2(别名B)为每个发件人接收者组分配一个行号。

最后,第二个subuqery的结果仅限于显示第一行并返回正确的有序发送方接收方对。

这会分解查询并显示每个子查询的结果,从而帮助解释其工作原理: http://rextester.com/CTD16984

这给了我们以下的SQL语句。

SELECT ID, Sender, Receiver
FROM (SELECT A.*
           , Case when user1 = @user1 and user2 = @user2 then @RN:=@RN+1 else @RN:=1 end as RN
           , case when user1 = @User1 then user1 else @user1:=user1 end u1
           , case when user2 = @User2 then user2 else @user2:=user2 end u2
      FROM (SELECT ID, sender, receiver
                 , case when Sender < Receiver then Sender else Receiver end user1
                 , case when Sender > Receiver then Sender else Receiver end user2
            FROM SQLFOo) A
      cross join (Select @RN:=0, @User1:='', @user2:='') b
      ORDER BY U1, U2, ID
      ) C
WHERE RN = 1
#based on last comment is this what you mean?
# AND (Sender = 10 or receiver = 10); 

答案 1 :(得分:1)

这个怎么样......

SELECT * FROM messages WHERE receiver NOT IN  
(SELECT sender FROM messages WHERE sender = 10 or receiver = 10 GROUP by sender)   
AND (sender = 10 OR receiver = 10);

这应该在内部查询中占用所有对,然后推断出碰撞的唯一方法是发送方=接收方和接收方=发送方,因此它会删除发送方=接收方的匹配。