MySql Присоединиться к условию Where, чтобы получить список данных - PullRequest
0 голосов
/ 24 октября 2018

Я создал следующие таблицы -

Комментарий:

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

Мета комментария:

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

со значением key в comment 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 вместо этого комментария или идентификатора ответа.удалить его из 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` table?

Примеры комментариев к данным:

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

Примеры комментариев к данным Meta:

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

Ожидаемый результат:

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

1 Ответ

0 голосов
/ 24 октября 2018

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 comment / 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`;

Вот ссылка на DBFiddle с этим рабочим примером

...