MySQL: вопрос LEFT JOIN, возвращает слишком много записей - PullRequest
0 голосов
/ 27 января 2020

Я получил следующую шему в MySQL

Таблица " items "

+--------+--------+-------------+
|item_id | name   | description |
+--------+--------+-------------+
|1       | Item 1 | Fist item   |
+--------+--------+-------------+

Таблица " items_relations "

+-----+---------+----------+
|id   | item_id | child_id |
+-----+---------+----------+
|1    | 1       | 1        |
+-----+---------+----------+
|2    | 1       | 2        |
+-----+---------+----------+

Таблица " дети "

+------------+-------+--------+
|children_id | color | weight |
+------------+-------+--------+
|1           | blue  | 5      |
+------------+-------+--------+
|2           | red   | NULL   |
+------------+-------+--------+

Таблица " комментарии "

+-----------+-----------+----------------+
|comment_id | parent_id | comment        |
+-----------+-----------+----------------+
|1          | 1         | Blablabla      |
+-----------+-----------+----------------+
|2          | 1         | Bliblibli      |
+-----------+-----------+----------------+

С этим я хочу вернуть через SQL запрос следующих данных:

  • item_id
  • имя
  • описание
  • количество комментариев
  • дочерние данные в формате JSON

Вот что я делаю, но данные JSON выглядят умноженными на количество строк или комментариев или дочерних элементов

SELECT i.item_id, i.name, i.description, count(comment_id) as nb_comm,
CONCAT('[', GROUP_CONCAT(CONCAT_WS('','{"color":"', color, '", "weight":"', weight,'"}')), ']') as data
FROM items i
LEFT JOIN comments c ON c.parent_id = i.item_id
LEFT JOIN items_relations ir ON ir.item_id = i.item_id
LEFT JOIN children ch ON ir.child_id = ch.children_id
WHERE 1

Поле данных содержит

[{"color":"blue", "weight":"5"},{"color":"blue", "weight":"5"},{"color":"red", "weight":"10"},{"color":"red", "weight":"10"}]

Что я могу сделать, чтобы иметь правильное содержимое в поле данных?

Вот SQL Fiddle

1 Ответ

2 голосов
/ 27 января 2020

Вы можете использовать DISTINCT для GROUP_CONCAT и COUNT

SELECT i.item_id, i.name, i.description, count(distinct comment_id) as nb_comm,
CONCAT('[', GROUP_CONCAT(DISTINCT CONCAT_WS('','{"color":"', color, '", "weight":"', weight,'"}')), ']') as data
FROM items i
LEFT JOIN comments c ON c.parent_id = i.item_id
LEFT JOIN items_relations ir ON ir.item_id = i.item_id
LEFT JOIN children ch ON ir.child_id = ch.children_id
GROUP BY i.item_id, i.name, i.description

http://sqlfiddle.com/#! 9 / 45b680 / 13

...