简体   繁体   English

选择所有匹配的两个字段,并使用mysql将这两个字段分组

[英]SELECT all matching two fields and grouping by those two fields with mysql

I have a messages system which doubles out as a message system and chat system, these are differentiated by a field called source. 我有一个消息系统,它可以作为消息系统和聊天系统使用,这些系统由一个名为source的字段区分。

I have the messages sections sorting and grouping properly however in the chat section it's not grouping these accordingly, please see my SQL below: 我有消息部分正确排序和分组,但是在聊天部分它没有相应地对这些进行分组,请参阅下面的SQL:

SELECT * 
FROM messages
WHERE ( senderID = "1" OR receiverID = "1" ) 
AND source = "1" 
GROUP BY receiverID, senderID 
ORDER BY addedDate DESC LIMIT 10

So the result i am expecting is just one per match, ie one per conversation 所以我期待的结果只是每场比赛一次,即每次对话一次

however am getting two for some reason. 但是由于某种原因我得到两个。

Thanks in advance 提前致谢

You are probably getting two answers per chat because you would have each person in both positions 你可能每次聊天都得到两个答案,因为你会让每个人都处于两个位置

ChatID  Sender Receiver
1       1      2
2       2      1
3       1      2
4       2      1

So, you'll have a record grouped by 
Sender / Receiver
1        2         and
2        1

I think what you are looking for is distinct people in the conversation where the above should be considered "ONE CHAT" regardless of the position they are in. To correct this, I would do something like... 我认为你所寻找的是与会者截然不同的人,无论他们处于什么位置,上述都应该被认为是“一个人”。为了纠正这个问题,我会做类似......

select 
      PreQuery.*,
      m2.Message,
      m2.SenderID,
      m2.ReceiverID
   from
      ( SELECT 
              if( m.senderID < m.receiverID, m.senderID, m.receiverID ) as Person1,
              if( m.senderID < m.receiverID, m.receiverID, m.senderID ) as Person2,
              max( m.ID ) as LastMessageIDPerChat,
              max( m.AddedDate ) as LastMessageDate
           FROM 
              messages m
           WHERE 
                  m.Source = "1"
              AND "1" IN ( SenderID, ReceiverID )
           GROUP BY
              Person1, 
              Person2
           ORDER BY 
              m.AddedDate DESC 
           LIMIT 10 ) PreQuery

         JOIN Messages m2
            on PreQuery.LastMessageIDPerChat = m2.ID

This will ensure that whichever ID is lower will always be in the first position, and whichever person's ID is higher is always in second position to prevent false duplicates as described above. 这将确保较低的ID始终位于第一位置,并且无论哪个人的ID较高,总是处于第二位置以防止如上所述的错误重复。

Also note... GROUP BY is typically expecting all non-group by fields to be associated with some aggregation, otherwise, it will just grab the first instance of a record found with a qualifying condition. 另请注意...... GROUP BY通常期望所有非group by字段与某些聚合相关联,否则,它将只获取具有限定条件的记录的第一个实例。 So, if you want to include same people in conversations on different days, you'll want to add "AddedDate" to the group by so it could have... 所以,如果你想在不同的日子里把同一个人包括在对话中,你就会想要将“AddedDate”添加到这个组中,这样就可以......

Person1   Person2  on 4/20
Person1   Person3  on 4/20
Person3   Person4  on 4/20
Person1   Person2  on 4/18
Person1   Person5  on 4/17
Person3   Person4  on 4/15

To get the status of who sent last, I had to wrap the query of paired people per conversation and get the last ID of that conversation. 为了获得最后发送的人的状态,我必须对每个对话的成对人员进行查询,并获得该对话的最后一个ID。 THEN, take that and re-join back to messages on that ID (if ID is actually the primary key ID of the messages table, adjust as needed). 然后,接受并重新加入该ID上的消息(如果ID实际上是消息表的主键ID,则根据需要进行调整)。 From the join, I can get the last message for the conversation AND who the sender ID and Receiver ID were for that transaction (and any other data you want from the now alias "m2" reference). 从联接中,我可以获得对话的最后一条消息以及发件人ID和Receiver ID对于该事务的用户(以及您希望从现在的别名“m2”引用中获得的任何其他数据)。

Are you sure your IDs aren't integers? 你确定你的ID不是整数吗?

SELECT
    receiverID,
    senderID,
    MAX(addedDate) as maxAddedDate
FROM 
    messages 
WHERE 
    ( 
        senderID = 1
        OR receiverID = 1 
    )  
    AND source = 1
GROUP BY
    receiverID, 
    senderID  
ORDER BY 
    addedDate DESC 
LIMIT 10 

Check this out. 看一下这个。

SELECT
    receiverID,
    senderID,
    MAX(addedDate) as maxAddedDate
FROM messages 
WHERE ( senderID = 1 OR receiverID = 1) AND source = 1
GROUP BY receiverID, senderID  
ORDER BY addedDate DESC 

You have not mentioned any aggregation for group by fields. 您没有提到按字段分组的任何聚合。

If your having multiple records according to any group by fields then what should happen? 如果您按字段按任意组记录多条记录,那么会发生什么?

you should have sum, count,... 你应该有总和,数,...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM