Получение всех родительских строк в одном SQL-запросе
У меня есть простая таблица MySQL, которая содержит список категорий, уровень определяется parent_id:
id name parent_id
---------------------------
1 Home 0
2 About 1
3 Contact 1
4 Legal 2
5 Privacy 4
6 Products 1
7 Support 1
Я пытаюсь сделать след. Поэтому у меня есть " id " ребенка, я хочу получить всех доступных родителей (повторяя цепочку, пока мы не достигнем 0 "Home"). Может быть любое число или дочерние строки, идущие на неограниченную глубину.
В настоящее время я использую вызов SQL для каждого родителя, это беспорядочно. Есть ли способ в SQL сделать это все на одном запрос?
5 ответов
адаптировано из здесь:
SELECT T2.id, T2.name
FROM (
SELECT
@r AS _id,
(SELECT @r := parent_id FROM table1 WHERE id = _id) AS parent_id,
@l := @l + 1 AS lvl
FROM
(SELECT @r := 5, @l := 0) vars,
table1 h
WHERE @r <> 0) T1
JOIN table1 T2
ON T1._id = T2.id
ORDER BY T1.lvl DESC
строку @r := 5
- номер страницы для текущей страницы. В результате получается следующее:
1, 'Home'
2, 'About'
4, 'Legal'
5, 'Privacy'
удивительный ответ Марка Байерса!
может быть, немного поздно на вечеринку, но если вы также хотите предотвратить бесконечный цикл, когда id = parent_id (т. е. когда данные были повреждены каким-то образом), вы можете расширить ответ следующим образом:
SELECT T2.id, T2.name
FROM (
SELECT
@r AS _id,
@p := @r AS previous
(SELECT @r := parent_id FROM table1 WHERE id = _id) AS parent_id,
@l := @l + 1 AS lvl
FROM
(SELECT @r := 5, @p := 0, @l := 0) vars,
table1 h
WHERE @r <> 0 AND @r <> @p) T1
JOIN table1 T2
ON T1._id = T2.id
ORDER BY T1.lvl DESC
В дополнение к вышеуказанным решениям:
post
-----
id
title
author
author
------
id
parent_id
name
[post]
id | title | author |
----------------------
1 | abc | 3 |
[author]
| id | parent_id | name |
|---------------------------|
| 1 | 0 | u1 |
| 2 | 1 | u2 |
| 3 | 2 | u3 |
| 4 | 0 | u4 |
автор, включая родителей, может иметь доступ к сообщению.
Я хочу проверить, имеет ли автор доступ к сообщению.
устранение:
дайте ID автора сообщения и верните всех его авторов и родителей автора
SELECT T2.id, T2.username
FROM (
SELECT @r AS _id,
(SELECT @r := parent_id FROM users WHERE id = _id) AS parent_id,
@l := @l + 1
FROM
(SELECT @r := 2, @l := 0) vars,
users h
WHERE @r <> 0) T1 JOIN users T2
ON T1._id = T2.id;
@r: = 2 => присвоение значения переменной @r.
Я думаю, нет простого способа сделать это, используя один запрос.
Я бы рекомендовал взглянуть на Вложенные Наборы, это, кажется, соответствует вашим потребностям.
насколько мне известно, нет.
эта статья Sitepoint может помочь вам.
вы можете получить все элементы с одним запросом, сохранить его в массиве, а затем выполнить итерацию, как объяснил здесь и здесь