Получение всех родительских строк в одном 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 может помочь вам.

вы можете получить все элементы с одним запросом, сохранить его в массиве, а затем выполнить итерацию, как объяснил здесь и здесь