MySQL:有没有办法从结果中消除重复的条目

时间:2014-01-21 19:16:56

标签: mysql sql

我有一个名为“message”的表,用于将消息从一个用户存储到另一个用户。我想制作一个消息框,其中包含特定用户的传入和传出消息。此消息框应包含两个用户之间的最后一条消息。所以,我必须消除两个用户之间的重复消息。我尝试了group by并删除了重复的邮件但我没有选择最新的邮件,因为order bygroup by之后有效。我尝试distinct函数来消除重复的消息。它运作良好,但我必须选择distinct

无法实现的所有列

我的留言表:

+-------+---------+------+-----+------------+
| id    | from_id | to_id| text| created_at |
+-------+---------+------+-----+------------+
| 1     | 1       | 2    | mes | 2014-01-16 |
| 2     | 2       | 1    | mes | 2014-01-17 |
| 3     | 1       | 3    | mes | 2014-01-18 | 
| 4     | 3       | 1    | mes | 2014-01-19 |
+-------+---------+------+-----+------------+

我的Group By SQL

SELECT * FROM message WHERE (from_id = 1 OR to_id = 1) GROUP BY(from_id + to_id) ORDER BY created_at DESC;

Distinct

SELECT DISTINCT(from_id + to_id) FROM message WHERE (from_id = 1 OR to_id = 1)

在上面的示例中,我想选择第二个和第四个消息。

有没有办法从结果中消除两个用户之间的重复消息?

编辑:我改进了示例

6 个答案:

答案 0 :(得分:1)

如果我正确理解您要实现的目标,您可以在MySQL中利用LEAST()GREATEST()函数和非标准GROUP BY扩展行为

SELECT id, from_id, to_id, text, created_at
  FROM
(
  SELECT id, from_id, to_id, text, created_at 
    FROM message
   ORDER BY LEAST(from_id, to_id), GREATEST(from_id, to_id), created_at DESC
) q
 GROUP BY LEAST(from_id, to_id), GREATEST(from_id, to_id)

这将为您提供每对用户的最后一条消息行。

输出:

+------+---------+-------+------+------------+
| id   | from_id | to_id | text | created_at |
+------+---------+-------+------+------------+
|    2 |       2 |     1 | mes  | 2014-01-17 |
|    4 |       3 |     1 | mes  | 2014-01-19 |
+------+---------+-------+------+------------+

这是 SQLFiddle 演示

答案 1 :(得分:1)

我尝试了分组依据,它消除了重复的邮件,但我没有选择最新的邮件,因为按group by

之后的工作顺序

所以你可以在之前订购:

SELECT * 
FROM (SELECT * FROM message ORDER BY created_at DESC)
WHERE (from_id = 1 OR to_id = 1) GROUP BY(from_id + to_id);

答案 2 :(得分:0)

您可以使用:

ORDER BY id DESC LIMIT 1

或通过时间戳(假设它包含数据和时间):

ORDER BY create_at DESC LIMIT 1

这将按降序对所有结果进行排序,并仅为您提供最后一行。

希望这有帮助!

答案 3 :(得分:0)

只需使用简单的选择。没有理由创建重复项。

SELECT from_id, to_id, text, created_at
FROM message
WHERE
(from_id = ? AND to_id = ??)
OR (from_id = ?? AND to_id = ?)

此处?代表一个ID,??代表另一个。

这里没有重复。订购可以通过以下几种方式实现:

按照最近的消息排序,无论发件人如何:

SELECT from_id, to_id, text, created_at
FROM message
WHERE
(from_id = ? AND to_id = ??)
OR (from_id = ?? AND to_id = ?)
ORDER BY created_at DESC

首先订购所有发件人邮件(然后按created_at)

SELECT from_id, to_id, text, created_at
FROM message
WHERE
(from_id = ? AND to_id = ??)
OR (from_id = ?? AND to_id = ?)
ORDER BY from_id = ? DESC, created_at DESC

答案 4 :(得分:0)

尝试在GROUP BY之后添加HAVING子句:HAVING COUNT(*)> 1

选择     列名,COUNT(*)  从     (选择DISTINCT             列名          从             消息

    ) 
    message

GROUP BY

列名 有计数(*)> 1

答案 5 :(得分:0)

SQL Fiddle

MySQL 5.5.32架构设置

CREATE TABLE message
    (`id` int, `from_id` int, `to_id` int, `text` varchar(3), `created_at` datetime)
;

INSERT INTO message
    (`id`, `from_id`, `to_id`, `text`, `created_at`)
VALUES
    (1, 1, 2, 'mes', '2014-01-16 00:00:00'),
    (2, 2, 1, 'MUL', '2014-01-17 00:00:00')
;

查询1

SELECT * 
FROM message 
WHERE from_id = 1 OR to_id = 1
ORDER BY created_at DESC
limit 1

<强> Results

| ID | FROM_ID | TO_ID | TEXT |                     CREATED_AT |
|----|---------|-------|------|--------------------------------|
|  2 |       2 |     1 |  MUL | January, 17 2014 00:00:00+0000 |