Как посчитать все сущности, приписанные - и потомки - корни в PostgreSQL? - PullRequest
0 голосов
/ 04 февраля 2020

У меня есть хитрый запрос, который поставил меня в тупик. По сути, у меня есть четыре основных типа транспортных средств в таблице, таблица деталей и таблица соединения между двумя типами parts_types (вставлено ниже).

Когда у меня возникает проблема, я пытаюсь сосчитать - все части в верхнем уровне - и дочерние (см. parent_id ниже) типы транспортных средств.

http://sqlfiddle.com/#! 15 / 6c4240 / 12

Мой запрос:

SELECT rt.root_id AS root_id, 
       rt.name AS root_name, 
       COUNT(tp.part_id) part_count
FROM types AS pt 
    LEFT OUTER JOIN types AS t ON pt.id = t.parent_id
    JOIN types_parts      AS tp ON tp.type_id = pt.id 
    JOIN parts            AS p  ON p.id = tp.part_id
    JOIN (SELECT id AS root_id, 
               name, 
               parent_id
          FROM 
               types 
          ) AS rt ON rt.root_id = pt.parent_id 
GROUP BY 1,2
ORDER BY 3 DESC

Нежелательный вывод:

+---------+-------------+------------+
| root_id | root_name   | part_count | 
+---------+-------------+------------+
| 2       | Automobiles | 12         |
+---------+-------------+------------+
| 8       | Trucks      | 8          | 
+---------+-------------+------------+
| 3       | Boats       | 5          |
+---------+-------------+------------+
| 7       | Cars        | 5          | 
+---------+-------------+------------+

Существует два основных вопроса:

  • Автомобили и грузовики должны быть сгруппированы в категории Автомобили.
  • Самолеты не указаны в списке, хотя есть части, относящиеся к Самолетам. Я предполагаю, что это потому, что у самолетов нет детей, таких как автомобили и лодки.
  • Это больше бонус, но «Дроны» не перечислены, потому что нет никаких частей, назначенных дронам. Было бы интересно понять, как по-прежнему включать его в этот отчет, но я не хочу замедлять запрос или усложнять его больше, чем нужно.

Требуемый выход:

+---------+-------------+------------+
| root_id | root_name   | part_count | 
+---------+-------------+------------+
| 2       | Automobiles | 12         | 
+---------+-------------+------------+
| 3       | Boats       | 8          | 
+---------+-------------+------------+
| 1       | Airplanes   | 3          |  
+---------+-------------+------------+
| 4       | Drones      | 0          |  
+---------+-------------+------------+

(точный счет в приведенной выше таблице не точен)

Таблица типов:

+----+-------------+-----------+--------------------------------+
| id | name        | parent_id | path                           |
+----+-------------+-----------+--------------------------------+
| 1  | Airplanes   | NULL      | /Airplanes                     |
+----+-------------+-----------+--------------------------------+
| 2  | Automobiles | NULL      | /Automobiles                   |
+----+-------------+-----------+--------------------------------+
| 3  | Boats       | NULL      | /Boats                         |
+----+-------------+-----------+--------------------------------+
| 4  | Drones      | NULL      | /Drones                        |
+----+-------------+-----------+--------------------------------+
| 5  | Tugboats    | 3         | /Boats/Tugboats                |
+----+-------------+-----------+--------------------------------+
| 6  | Battleship  | 2         | /Boats/Battleship              |
+----+-------------+-----------+--------------------------------+
| 7  | Cars        | 2         | /Automobiles/Cars              |
+----+-------------+-----------+--------------------------------+
| 8  | Trucks      | 2         | /Automobiles/Trucks            |
+----+-------------+-----------+--------------------------------+
| 9  | Convertible | 7         | /Automobiles/Cars/Convertible  |
+----+-------------+-----------+--------------------------------+
| 10 | Hatchback   | 7         | /Automobiles/Cars/Hatchback    |
+----+-------------+-----------+--------------------------------+
| 11 | Pickup      | 8         | /Automobiles/Trucks/Pickup     |
+----+-------------+-----------+--------------------------------+
| 12 | Dump Truck  | 8         | /Automobiles/Trucks/Dump Truck |
+----+-------------+-----------+--------------------------------+

Таблица деталей :

+----+--------------+
| id | name         |
+----+--------------+
| 1  | Wheels       |
+----+--------------+
| 2  | Wing         |
+----+--------------+
| 3  | Windshield   |
+----+--------------+
| 4  | Door         |
+----+--------------+
| 5  | Rims         |
+----+--------------+
| 6  | Tires        |
+----+--------------+
| 7  | Spark plugs  |
+----+--------------+
| 8  | Lifeboat     |
+----+--------------+
| 9  | Life jackets |
+----+--------------+
| 10 | Tailgate     |
+----+--------------+
| 11 | Giant tires  |
+----+--------------+
| 12 | Big guns     |
+----+--------------+
| 13 | Propeller    |
+----+--------------+
| 14 | Landing gear |
+----+--------------+

Таблица Types_Parts:

+---------+---------+-------+
| type_id | part_id | price |
+---------+---------+-------+
| 1       | 14      | 100   |
+---------+---------+-------+
| 1       | 13      | 200   |
+---------+---------+-------+
| 1       | 2       | 150   |
+---------+---------+-------+
| 7       | 1       | 300   |
+---------+---------+-------+
| 7       | 3       | 100   |
+---------+---------+-------+
| 7       | 4       | 200   |
+---------+---------+-------+
| 7       | 5       | 400   |
+---------+---------+-------+
| 7       | 6       | 100   |
+---------+---------+-------+
| 7       | 7       | 125   |
+---------+---------+-------+
| 5       | 6       | 300   |
+---------+---------+-------+
| 5       | 9       | 100   |
+---------+---------+-------+
| 6       | 8       | 200   |
+---------+---------+-------+
| 6       | 9       | 400   |
+---------+---------+-------+
| 6       | 12      | 350   |
+---------+---------+-------+
| 12      | 10      | 100   |
+---------+---------+-------+
| 12      | 11      | 110   |
+---------+---------+-------+
| 11      | 10      | 75    |
+---------+---------+-------+
| 11      | 1       | 100   |
+---------+---------+-------+
| 11      | 3       | 120   |
+---------+---------+-------+
| 11      | 4       | 160   |
+---------+---------+-------+
| 11      | 5       | 200   |
+---------+---------+-------+
| 11      | 6       | 240   |
+---------+---------+-------+
| 10      | 1       | 120   |
+---------+---------+-------+
| 10      | 3       | 160   |
+---------+---------+-------+
| 10      | 4       | 200   |
+---------+---------+-------+
| 10      | 5       | 240   |
+---------+---------+-------+
| 10      | 6       | 280   |
+---------+---------+-------+
...