SQL-запрос для выбора родительских и дочерних имен

#sql #hierarchical-data

#sql #иерархические-данные

Вопрос:

У меня есть таблица со следующей структурой —

 Category {Id, Name, ParentId}
  

У меня есть значения, подобные этому —

 id  name               parentid
-------------------------------
1   Technology Focus   NULL
2   Tools              1
3   Database           1
  

Как мне написать запрос, который отображается следующим образом —

 name (parent)      name (child)             
--------------------------------
Technology Focus   Tools
Technology Focus   Database
etc..
  

Я считаю, что мне нужно использовать предложение Group By, но я не совсем понимаю.

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

1. Что особенного в «технологическом фокусе»? Это категория?

2. Да, это так. Я просто хочу сгруппировать их в соответствии с их родительской категорией (именем).

Ответ №1:

если я правильно смотрю на это, я думаю, вам просто нужно

 select parent.name, child.name 
from category child
  inner join category parent
    on parent.id = child.parentid
  

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

1. Черт возьми, ты опередил меня примерно на 15 секунд.

Ответ №2:

Вам нужно объединить саму таблицу следующим образом:

 select Cat.Name, Par.Name
from category as cat
inner join category par on cat.id = par.id
  

Ответ №3:

Если вы пытаетесь реализовать древовидную структуру в SQL, то это, своего рода, неправильный способ сделать это.

Для реализации дерева следует использовать две таблицы:

 CREATE TABLE Categories (
   category_id INT AUTO_INCREMENT,
   name VARCHAR(40),
   PRIMARY KEY (category_id)
);
CREATE TABLE Tree (
   ancestor INT NOT NULL,
   descendant INT NOT NULL,
   PRIMARY KEY(ancestor, descendant),
   FOREIGN KEY (ancestor) REFERENCES Categories(category_id),
   FOREIGN KEY (descendant) REFERENCES Categories(category_id)
);
  

Эту структуру (известную как таблица закрытия) проще поддерживать (предварительно формировать обновления, изменять структуру и т.д.).

Затем вы выбираете данные, подобные:

 SELECT 
   parent.name AS parent,
   item.name AS item
FROM Categories AS parent
LEFT JOIN Tree AS path ON parent.category_id = path.ancestor
LEFT JOIN Categories AS item ON item.category_id = path.descendant
WHERE parent.category_id = 1
  

В любом случае, почитайте о таблицах замыкания, вы поймете почему ..