即使在切换时,MYSQL也会输入两列

时间:2017-03-11 21:20:15

标签: php mysql mysqli

我的mysql表具有以下结构:

ID    Sender    Recipient    Text
--    ------    ---------    ----
 1    10        11           Text
 2    10        11           Text
 3    11        10           Text
 4    11        10           Text
 5    12        13           Text
 6    13        12           Text
 7    14        15           Text
 8    14        15           Text
 9    17        16           Text
10    16        17           Text

此表表示两个用户之间的私人消息对话。我现在想要一个列表,我只显示每次聊天一次。通常情况下,我会在这种情况下使用一组,但后来我仍然有问题,因为发件人和收件人列也可以反过来。

我想收到这样的结果:

ID    Sender    Recipient    Text
--    ------    ---------    ----
 1    10        11           Text
 2    12        13           Text
 3    14        15           Text
 4    16        17           Text

所以每个对话都是独一无二的。 有谁知道如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

使用您的示例架构:

CREATE TABLE t (id int NOT NULL AUTO_INCREMENT, Sender int, Recipient int, Text varchar(50), primary key (id));
INSERT INTO t (Sender, Recipient, Text) VALUES (10, 11, 'Text');
INSERT INTO t (Sender, Recipient, Text) VALUES (10, 11, 'Text');
INSERT INTO t (Sender, Recipient, Text) VALUES (11, 10, 'Text');
INSERT INTO t (Sender, Recipient, Text) VALUES (11, 10, 'Text');
INSERT INTO t (Sender, Recipient, Text) VALUES (12, 13, 'Text');
INSERT INTO t (Sender, Recipient, Text) VALUES (13, 12, 'Text');
INSERT INTO t (Sender, Recipient, Text) VALUES (14, 15, 'Text');
INSERT INTO t (Sender, Recipient, Text) VALUES (14, 15, 'Text');
INSERT INTO t (Sender, Recipient, Text) VALUES (17, 16, 'Text');
INSERT INTO t (Sender, Recipient, Text) VALUES (16, 17, 'Text');

您可以编写此查询:

SELECT id, Sender, Recipient, Text
FROM t
JOIN (
        SELECT MAX(id) as last_id,
                CASE WHEN Sender < Recipient THEN CONCAT_WS('-', Sender, Recipient)
                     ELSE CONCAT_WS('-', Recipient, Sender)
                END as conversation
        FROM t
        GROUP BY conversation
    ) as t2 ON t2.last_id = t.id
;

输出结果为:

+------+----------+-------------+--------+
|   id |   Sender |   Recipient | Text   |
|------+----------+-------------+--------|
|    4 |       11 |          10 | Text   |
|    6 |       13 |          12 | Text   |
|    8 |       14 |          15 | Text   |
|   10 |       16 |          17 | Text   |
+------+----------+-------------+--------+
4 rows in set

答案 1 :(得分:1)

你可以使用这样的查询:

select
  min(id) as id,
  least(sender,recipient) as sender,
  greatest(sender,recipient) as recipient
  min(text) as text
from
  tablename
group by
  least(sender,recipient),
  greatest(sender,recipient)

(或者您可以为文本使用另一个聚合函数,例如group_concat,或者您必须连接两次tablename以获取聊天的第一个或最后一个消息,但这取决于您要返回的内容)