MySql список прямых и косвенных дочерних записей - PullRequest
0 голосов
/ 06 ноября 2018

У меня есть схема таблицы из 3 таблиц для обработки транспортных элементов. Транспорт может содержать несколько ящиков и несколько предметов. Помимо этого коробка также может содержать несколько элементов. Таким образом, предмет может быть прикреплен к транспорту прямо или косвенно.

Упрощенный DDL это:

CREATE TABLE transport (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `transport_number` varchar(50) NOT NULL,
  `transport_date` datetime NOT NULL
)

CREATE TABLE box (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(50) NOT NULL,
  `transport_id` int(11) NOT NULL
)

CREATE TABLE item (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(50) DEFAULT NULL,
  `box_id` int(11) DEFAULT NULL,
  `transport_id` int(11) DEFAULT NULL
)

Я пытаюсь реализовать запрос, который выбирает весь транспорт с полем и количеством элементов. Как то так:

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

TRANSPORT_ID | TRANSPORT_NUMBER | BOX_COUNT | ITEM_COUNT
--------------------------------------------------------
1            | T1               | 2         | 3
2            | T2               | 1         | 2

Пример данных

Транспорт:

ID     | TRANSPORT_NUMBER | TRANSPORT_DATE
------------------------------------------
1      | T1               | 2018-11-06
2      | T2               | 2018-11-06

Box:

ID     | TITLE            | TRANSPORT_ID
------------------------------------------
1      | B-1              | 1
2      | B-2              | 1
3      | B-3              | 2

Пункт:

ID     | TITLE            | BOX_ID    | TRANSPORT_ID
----------------------------------------------------
1      | I-1              | 1         | NULL
2      | I-2              | 2         | NULL
3      | I-3              | NULL      | 1
4      | I-4              | 3         | NULL
5      | I-5              | 3         | NULL

Ответы [ 2 ]

0 голосов
/ 06 ноября 2018

Одной из идей было бы реализовать все доступные отношения и затем их соответствующим образом суммировать:

SELECT 
t.id, 
t.transport_number, 
COUNT(distinct b.id) as box_count, 
COUNT(distinct i.id) + COUNT(distinct i2.id) as item_count
FROM transport t
LEFT JOIN box b ON t.id = b.transport_id
LEFT JOIN item i ON b.id = i.box_id
LEFT JOIN item i2 ON t.id = i2.transport_id
GROUP BY t.id
0 голосов
/ 06 ноября 2018

Это должно работать, если производительность не является проблемой:

SELECT 
  transport.id,
  transport.transport_number,
  (SELECT COUNT(*) FROM box WHERE box.transport_id = transport.id) AS box_count,
  (SELECT COUNT(*) FROM item WHERE item.transport_id = transport.id OR item.box_id IN (SELECT id FROM box WHERE box.transport_id = transport.id)) AS item_count
FROM transport;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...