SQL выбрать все товары из указанной категории и всех подкатегорий - PullRequest
1 голос
/ 11 января 2020

таблица элементов

id    category_id    item_title
1     2              Seagate SSHD
2     3              Seagtate 2.5 inch HDD
3     4              Western Digital 3.5 inch HDD
4     4              Toshiba 3.5 inch HDD
5     5              Generic Used Monitor
6     6              ASUS Monitor

таблица категорий

id    parent_id    category_title
1     0            Hardware
2     1            Hard Disks
3     2            Laptop Hard Disk
4     2            Desktop Hard Disk
5     1            Monitor
6     5            LCD Monitor

Визуальный:

                         -- Laptop Hard Disk
          -- Hard Disks |
 Harware-|               -- Desktop Hard Disk
          -- Monitors    -- LCD Monitor

Запрос:

SELECT * FROM items_table p
JOIN categories_table cp ON p.category_id = cp.id
JOIN categories_table cc ON cp.parent_id = cc.id
WHERE cc.id = "1"

Вывод

id    category_id    item_title
1     2              Seagate SSHD
5     5              Generic Used Monitor

Но я тоже пытаюсь получить предметы из всех подкатегорий, т.е. 1. при запросе родительской категории должно отображаться все, что относится к категории «родитель», «ребенок» и «внучка»; 2. при запросе дочерней категории должно отображаться все, что касается «ребенок» и «ребенок (внучка)»

Expectation; при запросе для категории 1 (оборудование)

id    category_id    item_title
1     2              Seagate SSHD
2     3              Seagtate 2.5 inch HDD
3     4              Western Digital 3.5 inch HDD
4     4              Toshiba 3.5 inch HDD
5     5              Generic Used Monitor
6     6              ASUS Monitor

при запросе для категории 2 (жесткие диски)

id    category_id    item_title
1     2              Seagate SSHD
2     3              Seagtate 2.5 inch HDD
3     4              Western Digital 3.5 inch HDD
4     4              Toshiba 3.5 inch HDD

Как изменить запрос, чтобы получить все элементы из категории и все это подкатегория?

1 Ответ

1 голос
/ 11 января 2020

Я должен предупредить, что метод id - parentId (известный как список смежности) не подходит для произвольного уровня вложенности. Но если вы знаете, что это будет только 3-уровневый, пусть будет так. В противном случае посмотрите на альтернативы, такие как «Вложенные наборы» или «Материализованные пути».

Решение состоит в том, чтобы получить все требуемые идентификаторы категорий для всех трех уровней категорий и затем применить их к таблице элементов.

SELECT *
FROM items
WHERE category_id IN (
  SELECT :cat_id AS id
    UNION ALL
  SELECT c2.id FROM categories AS c2 
  WHERE c2.parent_id = :cat_id
    UNION ALL
  SELECT c3.id FROM categories AS c3 
  JOIN categories AS c3p ON c3p.id = c3.parent_id 
  WHERE c3p.parent_id = :cat_id
)

См. https://www.db-fiddle.com/f/tCjGASjdJ4UP16dHugMzWi/1

...