I have a simple MySQL table thats contains a list of categories, level is determined by parent_id:
id name parent_id
---------------------------
1 Home
AFAIK no.
This Sitepoint article may help you.
You could retrieve all the elements with one query, store it in an array and then iterate, as explained here and here
I think, there's no easy way to do that, using one query.
I would recommend to take a look at Nested Sets, that seems to fit your needs.
I used the previous answers as examples to make smth more readable.
SELECT @org_id as id,
(SELECT name FROM test.organizations WHERE id = @org_id) as name,
(SELECT @org_id := parent_id FROM test.organizations WHERE id = @org_id) AS parent_id
FROM (SELECT @org_id := 4) vars, test.organizations org
WHERE @org_id is not NULL
ORDER BY id;
The result of execution looks like that:
(just for quick)
to check it yourself you need to enter values from the question into database test
, table organizations
CREATE TABLE organizations(
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(45) DEFAULT NULL,
parent_id int(11) DEFAULT NULL,
PRIMARY KEY (id));
insert into organizations values(1, "home", null);
insert into organizations values(2, "about", 1);
insert into organizations values(3, "contact", 1);
insert into organizations values(4, "legal", 2);
insert into organizations values(5, "privacy", 4);
insert into organizations values(6, "products", 1);
insert into organizations values(7, "support", 1);
Adapted from here:
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
The line @r := 5
is the page number for the current page. The result is as follows:
1, 'Home'
2, 'About'
4, 'Legal'
5, 'Privacy'
In addition to the above solutions:
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 |
an author including parents can have an access to the post.
I want to check whether author has an access to the post.
Solution:
give the post author's id and return all its authors and author's parents
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 => assigning value to @r variable.
Awesome answer by Mark Byers!
Maybe a bit late to the party, but if you also want to prevent an infinite loop when id = parent_id (i.e. somehow when data has been corrupted), you can expand the answer like this:
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