Pobieranie wszystkich wierszy nadrzędnych w jednym zapytaniu SQL

Mam prostą tabelę MySQL, która zawiera listę kategorii, poziom jest określony przez 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
[1]} próbuję zrobić szlak z okruszka chleba. Więc mam " id "dziecka, chcę, aby wszyscy dostępni rodzice(iteracja w górę łańcucha, aż osiągniemy 0 "Dom"). Może istnieć dowolna liczba lub wiersze potomne przechodzące do nieograniczonej głębokości.

Obecnie używam wywołania SQL dla każdego rodzica, to jest bałagan. Czy istnieje sposób w SQL, aby zrobić to wszystko na jednym zapytaniu?

Author: Bill Karwin, 2010-03-14

5 answers

Zaadaptowane z tutaj :

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

Linia @r := 5 jest numerem strony bieżącej strony. Wynik jest następujący:

1, 'Home'
2, 'About'
4, 'Legal'
5, 'Privacy'
 48
Author: Mark Byers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-14 14:24:27

Awesome answer by Mark Byers!

Może trochę późno dla strony, ale jeśli chcesz również zapobiec nieskończonej pętli, gdy id = parent_id (tzn. gdy dane zostały uszkodzone w jakiś sposób), możesz rozwinąć odpowiedź w następujący sposób:

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
 2
Author: Jos Theeuwen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-02 12:29:07

Oprócz powyższych rozwiązań:

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    |

Autor, w tym rodzice, może mieć dostęp do postu.

Chcę sprawdzić, czy autor ma dostęp do postu.

Rozwiązanie:

Podaj identyfikator autora postu i zwróć wszystkich jego autorów i rodziców autora

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 => przypisanie wartości zmiennej @r.

 1
Author: Sarvar Nishonboyev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-17 07:59:20

Myślę, że nie ma łatwego sposobu, aby to zrobić, używając jednego zapytania.

Polecam rzucić okiem na zagnieżdżone Zestawy , które wydają się pasować do Twoich potrzeb.

 0
Author: aztek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-14 11:22:08

AFAIK no.

Ten artykuł Sitepoint może Ci pomóc.

Można pobrać wszystkie elementy za pomocą jednego zapytania, zapisać je w tablicy, a następnie iterate, jak wyjaśniono TUTAJ i tutaj

 -2
Author: Shuriken,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-14 12:05:26