MySql Join条件与Where条件获取数据列表

时间:2018-10-24 07:37:51

标签: mysql left-join

我创建了以下表格-

评论:

|  column   |    type     |
+-----------+-------------+
| comment_id| int(11)     |
| comment   | longText    |
| parent_id | int(11)     |
+-----------+-------------+

评论元:

|  column   |    type     |
+-----------+-------------+
| comment_id| int(11)     |
| key       | varchar(40) |
| value     | varchar(50) |
+-----------+-------------+

keycomment meta中具有(delete, reply_count, report)值。

数据通过以下方式添加到表中:

  • 用户写评论时,会将其添加到comments数据库中,并且parent_id设置为0。
  • 当用户为特定评论写回复时,会将其添加到comments数据库中,其中parent_id设置为评论的comment_id,并且reply_count' is updated in the comments_meta`数据库发表评论。
  • 当用户删除评论或回复时,值会在comments_meta数据库中更新,但将key设置为delete,将value设置为1该评论或回复ID,而不是将其从comments数据库中删除。

我只想获取所有未删除的评论的列表。

直到现在我都尝试过:

select comments.comment_id,comments.comment, ifnull(comments_meta.value,0) as reply_count from comments left join comments_meta on comments_meta.comment_id = comments.comment_id and comments_meta.meta_key = "reply_count";

这给了我所有的评论,包括删除的评论。

是否可以使用此表模型获取列表? 还是我必须附加属性delete或'reply_count with评论`表之一?

示例数据注释:

|comment_id |    comment  |  parent_id  |  
+-----------+-------------+-------------+
|    1      | comment1    |      0      | 
|    2      | comment2    |      0      |
|    3      | reply1      |      1      |
|    4      | reply2      |      1      |
|    5      | comment3    |      0      |
+-----------+-------------+-------------+

示例数据注释元:

|comment_id |     key     |    value    |  
+-----------+-------------+-------------+
|    2      |   delete    |      1      | 
|    1      | reply_count |      2      |
+-----------+-------------+-------------+

预期输出:

|comment_id |    comment  | reply_count |  
+-----------+-------------+-------------+
|    1      |  comment1   |      2      | 
|    5      |  comment3   |      0      |
+-----------+-------------+-------------+

1 个答案:

答案 0 :(得分:1)

DDL:

create table `comment`(
  `comment_id` int not null auto_increment,
  `comment` varchar(128),
  `parent_id` int not null,
  primary key(`comment_id`)
);


insert into `comment`(`comment_id`,`comment`,`parent_id`) values
(1,'comment1',0),
(2,'comment2',0),
(3,'reply1',1),
(4,'reply2',1),
(5,'comment3',0);

create table `comment_meta`(
  `comment_id` int not null,
  `key` varchar(128),
  `value` int not null,
  primary key(`comment_id`,`key`)
);

insert into `comment_meta`(`comment_id`,`key`,`value`) values
(2,'delete',1),
(1,'reply_count',2);

让我们只获得“根”注释:

  SELECT * FROM `comment` 
  WHERE `parent_id` = 0

让我们只选择评论:

  SELECT * FROM `comment` 
  WHERE `parent_id` != 0 

让我们联接(外部-列出所有根注释)这两个子查询,看看我们得到了什么:

SELECT *
FROM
(
  SELECT * FROM `comment` 
  WHERE `parent_id` = 0
) AS `root_comments`
LEFT JOIN 
(
  SELECT * FROM `comment` 
  WHERE `parent_id` != 0  
) `replies` ON `replies`.`parent_id` = `root_comments`.`comment_id`;

我们得到类似this的内容: enter image description here

现在,让我们在结果集中添加一列,以显示该行表示根评论(0)还是回复(1):

SELECT *,IF(`replies`.`comment_id` IS NOT NULL, 1, 0)
FROM
(
  SELECT * FROM `comment` 
  WHERE `parent_id` = 0
) AS `root_comments`
LEFT JOIN 
(
  SELECT * FROM `comment` 
  WHERE `parent_id` != 0  
) `replies` ON `replies`.`parent_id` = `root_comments`.`comment_id`;

让我们选择已删除的评论:

SELECT * FROM `comment_meta`
WHERE `key` = 'delete'

将其与当前拥有的内容结合起来,并添加一个WHERE条件以仅考虑那些注释,这些注释在元表中没有对应的带有'delete'键的行:

WHERE `deleted_comments`.`comment_id` IS NULL

最后,我们只需要选择所需的列,并为每个评论选择GROUP BY条评论/ SUM()的答复(1):

请注意,在MySQL 5.7中,GROUP BY的默认模式已更改,并且如果不更改此设置,就无法SUM个非分组列。

SELECT `root_comments`.`comment_id`,`root_comments`.`comment`,SUM(IF(`replies`.`comment_id` IS NOT NULL, 1, 0)) AS reply_count
FROM
(
  SELECT * FROM `comment` 
  WHERE `parent_id` = 0
) AS `root_comments`
LEFT JOIN 
(
  SELECT * FROM `comment` 
  WHERE `parent_id` != 0  
) `replies` ON `replies`.`parent_id` = `root_comments`.`comment_id`
LEFT JOIN 
(
  SELECT * FROM `comment_meta`
  WHERE `key` = 'delete'
) `deleted_comments` ON `deleted_comments`.`comment_id` = `root_comments`.`comment_id`
WHERE `deleted_comments`.`comment_id` IS NULL
GROUP BY `root_comments`.`comment_id`;

下面是此示例的link到DBFiddle