首页 > 解决方案 > 在 MySQL 的连接子查询中使用 DISTINCT

问题描述

这是这个问题的小提琴:http ://sqlfiddle.com/#!9/0569eb/1

我有一个评论表,回复存储在同一个表中,如下所示。

CREATE TABLE IF NOT EXISTS `comments` (
  `id` int(6) unsigned NOT NULL,
  `parent` int(3) unsigned NOT NULL,
  `posted_by` int(3) unsigned NOT NULL,
  `comment` varchar(200) NOT NULL,
  `sort` int(3) NOT NULL,
  PRIMARY KEY (`id`),
  INDEX (`parent`),
  INDEX (`posted_by`),
  INDEX (`sort`)
  
) DEFAULT CHARSET=utf8;
INSERT INTO `comments` (`id`, `parent`, `posted_by`, `comment`, `sort`) VALUES
  ('1', '0', '1', 'Here is a comment by user 1', '5'),
  ('2', '1', '2', 'Here is a reply by user 2', '5'),
  ('3', '1', '3', 'Here is a reply by user 3', '5'),
  ('4', '1', '2', 'Here is a reply by user 2', '5'),
  ('5', '0', '2', 'Here is a comment by user 2', '2'),
  ('6', '0', '5', 'Here is a comment by user 5', '3');

我需要能够选择用户发布的主要评论,或者让同一用户发布回复。以下是我想出的为用户 2 获取适当数据的方法。

由于单个评论可以有多个回复,因此我在子查询中使用 DISTINCT 以每行仅获得一个回复。这是一个合适的解决方案,还是有更好的方法来处理这种情况?

SELECT
  c.id,
  c.comment
FROM comments c
  LEFT JOIN (SELECT DISTINCT comments.parent FROM comments WHERE comments.posted_by = 2) r ON r.parent = c.id
WHERE 
  (
    c.posted_by = 2
    OR r.parent IS NOT NULL
  )
  AND c.parent=0
ORDER BY c.sort DESC;

以下是与用户 2 相关的评论的预期输出

在此处输入图像描述

标签: mysqljoingroup-by

解决方案


已编辑:按照评论中的建议消除对结果进行排序的需要

您的解决方案没有任何问题,它可以工作并且尽可能简洁。

作为替代方案(但不是更好),您可以使用 UNION

SELECT id, comment 
FROM (
    SELECT 
        c.id, 
        c.comment,
        c.sort
    FROM comments c
    WHERE posted_by = 2 AND parent = 0
    UNION
    SELECT DISTINCT
        c.id, 
        c.comment,
        c.sort
    FROM comments c
        JOIN comments p ON p.parent = c.id 
    WHERE p.posted_by = 2) x
ORDER BY sort DESC;

推荐阅读