SQL:如何按两列的唯一组合进行分组?

Sto*_*ler 5 mysql sql heidisql

语境:

  • message有列from_user_idto_user_id
  • 用户应该看到最近的对话以及显示的最后一条消息
  • 一个会话由多条消息组成,这些消息具有相同的用户 ID 组合(用户发送消息、用户接收消息)

表格内容:

+-------------------------------------------------+--------------+------------+
| text                                            | from_user_id | to_user_id |
+-------------------------------------------------+--------------+------------+
| Hi there!                                       |           13 |         14 | <- Liara to Penelope
| Oh hi, how are you?                             |           14 |         13 | <- Penelope to Liara
| Fine, thanks for asking. How are you?           |           13 |         14 | <- Liara to Penelope
| Could not be better! How are things over there? |           14 |         13 | <- Penelope to Liara
| Hi, I just spoke to Penelope!                   |           13 |         15 | <- Liara to Zara
| Oh you did? How is she?                         |           15 |         13 | <- Zara to Liara
| Liara told me you guys texted, how are things?  |           15 |         14 | <- Zara to Penelope
| Fine, she's good, too                           |           14 |         15 | <- Penelope to Zara
+-------------------------------------------------+--------------+------------+
Run Code Online (Sandbox Code Playgroud)

from_user_id我的尝试是按和进行分组to_user_id,但显然我得到了用户收到的一组消息和用户发送的另一组消息。

SELECT text, from_user_id, to_user_id,created FROM message 
WHERE from_user_id=13 or to_user_id=13
GROUP BY from_user_id, to_user_id
ORDER BY created DESC
Run Code Online (Sandbox Code Playgroud)

让我明白:

+-------------------------------+--------------+------------+---------------------+
| text                          | from_user_id | to_user_id | created             |
+-------------------------------+--------------+------------+---------------------+
| Oh you did? How is she?       |           15 |         13 | 2017-09-01 21:45:14 | <- received by Liara
| Hi, I just spoke to Penelope! |           13 |         15 | 2017-09-01 21:44:51 | <- send by Liara
| Oh hi, how are you?           |           14 |         13 | 2017-09-01 17:06:53 |
| Hi there!                     |           13 |         14 | 2017-09-01 17:06:29 |
+-------------------------------+--------------+------------+---------------------+
Run Code Online (Sandbox Code Playgroud)

虽然我想要:

+-------------------------------+--------------+------------+---------------------+
| text                          | from_user_id | to_user_id | created             |
+-------------------------------+--------------+------------+---------------------+
| Oh you did? How is she?       |           15 |         13 | 2017-09-01 21:45:14 | <- Last message of conversation with Zara
| Oh hi, how are you?           |           14 |         13 | 2017-09-01 17:06:53 |
+-------------------------------+--------------+------------+---------------------+
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

编辑:使用leastorgreatest也不会产生所需的结果。它确实正确地对条目进行了分组,但正如您在结果中看到的那样,最后一条消息不正确。

+----+-------------------------------------------------+------+---------------------+--------------+------------+
| id | text                                            | read | created             | from_user_id | to_user_id |
+----+-------------------------------------------------+------+---------------------+--------------+------------+
|  8 | Oh you did? How is she?                         | No   | 2017-09-01 21:45:14 |           15 |         13 |
|  5 | Could not be better! How are things over there? | No   | 2017-09-01 17:07:47 |           14 |         13 |
+----+-------------------------------------------------+------+---------------------+--------------+------------+
Run Code Online (Sandbox Code Playgroud)

Gor*_*off 2

执行您想要的操作的一种方法是使用相关子查询来查找匹配对话的最小创建日期/时间:

SELECT m.*
FROM message m
WHERE 13 in (from_user_id, to_user_id) AND
      m.created = (SELECT MAX(m2.created)
                   FROM message m2
                   WHERE (m2.from_user_id = m.from_user_id AND m2.to_user_id = m.to_user_id) OR
                         (m2.from_user_id = m.to_user_id AND m2.to_user_id = m.from_user_id) 
                  )
ORDER BY m.created DESC
Run Code Online (Sandbox Code Playgroud)