How to get related row from same table? - php

I have a table like this:
// mytable
+----+---------+---------+
| id | related | color |
+----+---------+---------+
| 1 | 1 | red |
| 2 | 1 | blue |
| 3 | 3 | green |
| 4 | 1 | white |
| 5 | 3 | brown |
| 6 | 6 | gray |
| 7 | 3 | black |
| 8 | 1 | orange |
| 9 | 6 | pink |
+----+---------+---------+
I have an id number and I need to get the color of related id.
For example:
$id = 4; // I need to get `red`
$id = 5; // I need to get `green`
$id = 6; // I need to get `gray`
$id = 9; // I need to get `gray`
I can do that by using a JOIN. Something like this:
SELECT t2.color FROM mytable t1 JOIN mytable t2 ON t1.related = t2.id WHERE t1.id = :id
My query works as expected .. But I'm not sure using a JOIN for doing that is standard. Actually I'm trying to know is there any better approach? Or mine is a normal way?

What's wrong with SELECT t.related FROM mytable t WHERE t.id = :id? JOIN makes nothing more but checking if there is a actual id in 'related' column or not

I've done two different query and explain them, hope can give you some hints.
SQL Fiddle
MySQL 5.6 Schema:
CREATE TABLE mytable
(`id` int, `related` int, `color` varchar(6))
;
INSERT INTO mytable
(`id`, `related`, `color`)
VALUES
(1, 1, 'red'),
(2, 1, 'blue'),
(3, 3, 'green'),
(4, 1, 'white'),
(5, 3, 'brown'),
(6, 6, 'gray'),
(7, 3, 'black'),
(8, 1, 'orange'),
(9, 6, 'pink')
;
Query 1:
SELECT t2.color FROM mytable t1 JOIN mytable t2 ON t1.related = t2.id WHERE t1.id = '4'
Results:
| color |
|-------|
| red |
Query 2:
explain SELECT t2.color FROM mytable t1 JOIN mytable t2 ON t1.related = t2.id WHERE t1.id = '4'
Results:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
|----|-------------|-------|------|---------------|--------|---------|--------|------|----------------------------------------------------|
| 1 | SIMPLE | t1 | ALL | (null) | (null) | (null) | (null) | 9 | Using where |
| 1 | SIMPLE | t2 | ALL | (null) | (null) | (null) | (null) | 9 | Using where; Using join buffer (Block Nested Loop) |
Query 3:
SELECT t1.color FROM mytable t1 WHERE exists (select 1 from mytable t2 where t1.id = t2.related and t2.id ='4')
Results:
| color |
|-------|
| red |
Query 4:
explain SELECT t1.color FROM mytable t1 WHERE exists (select 1 from mytable t2 where t1.id = t2.related and t2.id ='4')
Results:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
|----|--------------------|-------|------|---------------|--------|---------|--------|------|-------------|
| 1 | PRIMARY | t1 | ALL | (null) | (null) | (null) | (null) | 9 | Using where |
| 2 | DEPENDENT SUBQUERY | t2 | ALL | (null) | (null) | (null) | (null) | 9 | Using where |

you can handle this in simple ways also
select t.color from mytable t where t.id = '$id' (for one value)
select t.color from mytable t where t.id in ('$id1','$id2','$id3','$id4' ) (for multi-values comma separated strings)

Related

copy (with update) certain content from the same table

I wanted to UPDATE the value of my below table (row & col_md) :
Current Data
| id | id_cat | row | col_md |
| --- | ------ | ---- | ------ |
| 1 | 1 | 1 | 4 |
| 2 | 1 | 2 | 5 |
| 3 | 1 | 3 | 5 |
| 4 | 2 | 1 | 3 |
| 5 | 2 | 2 | 4 |
| 6 | 2 | 2 | 4 |
| 7 | 3 | 1 | 12 |
| 8 | 3 | 1 | 12 |
| 9 | 3 | 2 | 3 |
That may look something like the below table. (I want to have the same content of rows that id_cat=1 have, in rows with id_cat=2 & 3).
Required Data:
| id | id_cat | row | col_md |
| --- | ------ | ---- | ------ |
| 1 | 1 | 1 | 4 |
| 2 | 1 | 2 | 5 |
| 3 | 1 | 3 | 5 |
| 4 | 2 | 1 | 4 |
| 5 | 2 | 2 | 5 |
| 6 | 2 | 3 | 5 |
| 7 | 3 | 1 | 4 |
| 8 | 3 | 2 | 5 |
| 9 | 3 | 3 | 5 |
id_cat 2 and 3 should have the same "row" and "col_md" values as in id_cat=1.
I've tried with this post first answer like this:
UPDATE `myTable` AS t1 JOIN `myTable` AS t2 ON t2.id_cat=1
SET t1.row = t2.row, t1.col_md = t2.col_md
WHERE t1.id_cat = 2 or t1.id_cat=3;
but that results on all "row" column values equal to 1.
What I'm doing wrong and what's the way to do this right?
EDIT:
The tables above are just examples to make this ask easier to understand, but the real table is bigger (4k rows) and:
"row" column with id_cat=1 can have any number and not a sequence as in the example.
"col_md" columns can have any number too.
That's why the update must set a copy of the id_cat=1 "row" and "col_md" values in the id_cat!=1 "row" and "col_md" values.
If this can't be done with just MySQL, a php script will be nice too.
In the example query you gave, you are updating t1.row with t2.row. As you are joining on the id_cat, this will result in multiple rows selected to update a single row, so the outcome just takes the first row.
What you actually want, is to make the 1-to-1 relation in the update, so what needs to be changed in your query is to add the row matching in the join and remove the assignment in the SET, like this:
UPDATE `myTable` AS t1 JOIN `myTable` AS t2 ON t2.id_cat=1 AND t1.row = t2.row
SET t1.col_md = t2.col_md
WHERE t1.id_cat = 2 or t1.id_cat=3;
Which then gives the output of:
MariaDB [testart]> select * from myTable;
+------+--------+------+--------+
| id | id_cat | row | col_md |
+------+--------+------+--------+
| 1 | 1 | 1 | 4 |
| 2 | 1 | 2 | 5 |
| 3 | 1 | 3 | 5 |
| 4 | 2 | 1 | 4 |
| 5 | 2 | 2 | 5 |
| 6 | 2 | 3 | 5 |
| 7 | 3 | 1 | 4 |
| 8 | 3 | 1 | 4 |
| 9 | 3 | 2 | 5 |
+------+--------+------+--------+
9 rows in set (0.00 sec)
Currently able to achieve the SQL query for your desired result.
SELECT t2.id_cat, t1.row, t1.col_md
FROM (SELECT row, col_md from mytable WHERE id_cat=1) as t1 , mytable as t2
GROUP BY t2.id_cat, t1.row, t1.col_md
The above will return the following..
I suggest to use INSERT statement along with the above query to put the record into a new table and drop the old one.
Cheers!
EDITED...
Instead of Updating table, alternate approach could be to Insert the required record into a new table.
This can be achieved with following four steps
Create a tmp table with same fileds (id Auto_Increment, id_cat, row, col_md)
Insert to tmp table with this statement...
INSERT INTO tmp(id_cat, row, col_md)
SELECT t2.id_cat, t1.row, t1.col_md
FROM (SELECT row, col_md from mytable WHERE id_cat=1) as t1 , mytable as t2
GROUP BY t2.id_cat, t1.row, t1.col_md
Remove/Rename 'myTable'.
Rename 'tmp' table to 'myTable'.
Hope this will serve the purpose...
Cheers!
it's not enough to tell which group you want the data from, you need to match id to id.
in your case t2.id 4 and 7 to t1.id 1, t2.id 5 and 8 to t1.id 2, and t2.id 6 and 9 to t1.id 3.
SELECT #d := COUNT(*) FROM myTable WHERE id_cat = 1;
UPDATE `myTable` AS t1
JOIN `myTable` AS t2 ON t2.id_cat=1 AND
t2.id = IFNULL(NULLIF(t1.id MOD #d, 0), #d)
SET t1.row = t2.row, t1.col_md = t2.col_md
WHERE t1.id_cat = 2 or t1.id_cat=3;
#d holds the number of lines where id_cat = 1
we divide t1.id by #d and match the remainder (MOD) to t2.id.
when t1.id is multiple of #d the remainder is 0 and we have to match it to #d
so we make 0 into NULL and NULL into #d
In my understanding, the difficult part about this question is to relate each record to update (ie each record with id_cat IN (2, 3)) to the relevant original record (record with id_cat = 1).
Based on your sample data, I understand that you expect series of records for each id_cat (I can see three groups of three records, sorted by increasing id), so I would assume that you want to relate each record to the original that has the same sequence in the group of record where id_cat = 1.
Assuming MySQL 8.0, a typical approach to assign a number to a record within a group is ROW_NUMBER(). Consider this simple query:
SELECT
t.*,
ROW_NUMBER() OVER(PARTITION BY id_cat ORDER BY id) rn
FROM t
Yields:
| id | id_cat | rw | col_md | rn |
| --- | ------ | --- | ------ | --- |
| 1 | 1 | 1 | 4 | 1 |
| 2 | 1 | 2 | 5 | 2 |
| 3 | 1 | 3 | 5 | 3 |
| 4 | 2 | 1 | 3 | 1 |
| 5 | 2 | 2 | 4 | 2 |
| 6 | 2 | 2 | 4 | 3 |
| 7 | 3 | 1 | 12 | 1 |
| 8 | 3 | 1 | 12 | 2 |
| 9 | 3 | 2 | 3 | 3 |
Now with this set-up in mind, we can turn this query to a Common Table Expression (available also starting MySQL 8.0), and JOIN it as need with the original table to do the UPDATE:
WITH cte AS (
SELECT
t.*,
ROW_NUMBER() OVER(PARTITION BY id_cat ORDER BY id) rn
FROM t
)
UPDATE t t0
INNER JOIN cte t1 ON t1.id = t0.id
INNER JOIN cte t2 ON t2.id_cat = 1 AND t2.rn = t1.rn
SET t0.rw = t2.rw, t0.col_md = t2.col_md
WHERE t0.id_cat IN (2, 3)
Details:
t0 is the original table, where records having id_cat IN (2, 3) need to be updated
t1 is the corresponding record in the CTE (to which a row number was assigned)
t2 is the record in the CTE that has id_cat = 1 and the same row number as the record being updated
Demo on DB Fiddle:
| id | id_cat | rw | col_md |
| --- | ------ | --- | ------ |
| 1 | 1 | 1 | 4 |
| 2 | 1 | 2 | 5 |
| 3 | 1 | 3 | 5 |
| 4 | 2 | 1 | 4 |
| 5 | 2 | 2 | 5 |
| 6 | 2 | 3 | 5 |
| 7 | 3 | 1 | 4 |
| 8 | 3 | 2 | 5 |
| 9 | 3 | 3 | 5 |

Query with intermediate table in MySQL

I'm trying to make a query with an intermediate table with very important data (field called "quantity") and I can't show all the data that I need
The tables are
TP_PANTONE_COLORS
id_pantone_color (primary key)
name_pantone_color
hex_pantone_color
TP_COLOR_CART
id_color_cart (primary key)
name_color_cart
description
link
TP_PANTONE_BASE (intermediate)
id_quantity (primary key)
id_pantone_color
id_color_cart
quantity
I need a table like this
NAME_PANTONE_COLOR | NAME_COLOR_CART | QUANTITY | LINK
I'm trying with
SELECT * FROM tp_color_cart A
INNER JOIN tp_pantone_base B ON
A.id_color_cart = B.id_color_cart
INNER JOIN tp_pantone_colors C ON
C.id_pantone_color = B.id_pantone_color
WHERE id_pantone_color=1
and
SELECT
A.name_pantone_color AS 'NAME_PANTONE_COLOR' ,
C.name_color_cart AS 'NAME_COLOR_CART',
B.quantity AS 'QUANTITY',
C.link AS 'LINK'
FROM tp_pantone_colors A
JOIN tp_pantone_base B ON B.id_pantone_color=A.id_pantone_color
INNER JOIN tp_color_cart C ON B.id_color_cart=C.id_color_cart
WHERE A.id_pantone_color=1
but this queries returns one row and TP_PANTONE_BASE have 4 rows with id_pantone_color=1
I cannot reproduce your problem. Given the appropriate data I would expect your query to return 4 rows even if there was only 1 record in TP_PANTONE_BASE and tp_color_cart
for example
drop table if exists tp_pantone_colors,TP_PANTONE_BASE,TP_COLOR_CART;
create table TP_PANTONE_COLORS(
id_pantone_color int,
name_pantone_color varchar(1),
hex_pantone_color int
);
insert into TP_PANTONE_COLORS values
(1,'a',1),(1,'a',1),(1,'a',1),(1,'a',1);
create table TP_COLOR_CART(
id_color_cart int,
name_color_cart varchar(1),
description varchar(2),
link int
);
insert into tp_color_cart values
(1,'b','bb',1);
create table TP_PANTONE_BASE (
id_quantity int,
id_pantone_color int,
id_color_cart int,
quantity int
);
insert into TP_PANTONE_BASE values
(1,1,1,10);
select A.name_pantone_color AS 'NAME_PANTONE_COLOR' ,
C.name_color_cart AS 'NAME_COLOR_CART',
B.quantity AS 'QUANTITY',
C.link AS 'LINK'
from tp_pantone_colors a
join TP_PANTONE_BASE b on b.id_pantone_color = a.id_pantone_color
join TP_COLOR_CART c on c.id_color_cart = b.id_color_cart;
+--------------------+-----------------+----------+------+
| NAME_PANTONE_COLOR | NAME_COLOR_CART | QUANTITY | LINK |
+--------------------+-----------------+----------+------+
| a | b | 10 | 1 |
| a | b | 10 | 1 |
| a | b | 10 | 1 |
| a | b | 10 | 1 |
+--------------------+-----------------+----------+------+
4 rows in set (0.00 sec)
In other words we cannot solve this without sample data from you.
Based on your data
SELECT A.id_pantone_color,b.*
from tp_pantone_colors a
join TP_PANTONE_BASE b on b.id_pantone_color = a.id_pantone_color
WHERE A.id_pantone_color=1;
+------------------+-------------+------------------+---------------+----------+
| id_pantone_color | id_quantity | id_pantone_color | id_color_cart | quantity |
+------------------+-------------+------------------+---------------+----------+
| 1 | 1 | 1 | 30 | 13,693 |
| 1 | 2247 | 1 | 452 | 13,543 |
| 1 | 5616 | 1 | 453 | 2,55 |
| 1 | 7862 | 1 | 455 | 70,215 |
+------------------+-------------+------------------+---------------+----------+
4 rows in set (0.00 sec)
select * from TP_COLOR_CART where id_color_cart in(30,452,453,455)
+---------------+-----------------+-------------+---------+------+
| id_color_cart | name_color_cart | description | color | link |
+---------------+-----------------+-------------+---------+------+
| 30 | 001 | White | #FFFFFF | # |
+---------------+-----------------+-------------+---------+------+
1 row in set (0.00 sec)
If you want you could
select A.name_pantone_color AS 'NAME_PANTONE_COLOR' ,
C.name_color_cart AS 'NAME_COLOR_CART',
B.quantity AS 'QUANTITY',
C.link AS 'LINK'
from tp_pantone_colors a
join TP_PANTONE_BASE b on b.id_pantone_color = a.id_pantone_color
left join TP_COLOR_CART c on c.id_color_cart = b.id_color_cart
WHERE A.id_pantone_color=1;
+--------------------+-----------------+----------+------+
| NAME_PANTONE_COLOR | NAME_COLOR_CART | QUANTITY | LINK |
+--------------------+-----------------+----------+------+
| PANTONE 1605 C | 001 | 13,693 | # |
| PANTONE 1605 C | NULL | 13,543 | NULL |
| PANTONE 1605 C | NULL | 2,55 | NULL |
| PANTONE 1605 C | NULL | 70,215 | NULL |
+--------------------+-----------------+----------+------+
4 rows in set (0.02 sec)
But it's not your query that's wrong it's the data.

Use outer alias in subquery with 4 Tables in mysql

Hello guys I have 4 tables as an key-value store in mysql
t1 (article): t2:
| id | date | | id | key | value |
------------- ---------------------------
| 1 | 2016 | | 1 | title | title1 |
| 2 | 2017 | | 1 | user_id | 1 |
| 3 | 2018 | | 2 | title | title2 |
------------- | 2 | user_id | 2 |
| 3 | title | title3 |
| 3 | user_id | 1 |
---------------------------
t1 (user): t2:
| id | date | | id | key | value |
------------- -------------------------
| 1 | NULL | | 1 | name | user1 |
| 2 | NULL | | 2 | name | user2 |
------------- -------------------------
SELECT t1.id,
GROUP_CONCAT(IF(t2.key='title',t2.value,NULL)) AS title,
t1.date,
GROUP_CONCAT(IF(t2.key='user_id',t2.value,NULL)) AS user_id,
(
SELECT GROUP_CONCAT(IF(t4.key='user_name',t4.value,NULL))
FROM t4
GROUP BY t4.id
HAVING t4.id = user_id
) AS user_name
FROM t1
INNER JOIN t2
ON t1.id = t2.id
GROUP BY t1.id
i want to print out the name of the user that is stored as an id in t2 like:
| id | title | date | user_id | user_name |
------------------------------------------------
| 1 | title1 | 2016 | 1 | user1 |
| 2 | title2 | 2017 | 2 | user2 |
| 3 | title3 | 2018 | 1 | user1 |
------------------------------------------------
i have tested WHERE clause and HAVING clause, but nothing works for me.
I found your table references way too confusing, so I used an interpretation of the sample data. I only needed 3 of the 4 tables by the way. Demo
MySQL 5.6 Schema Setup:
CREATE TABLE articles
(`id` int, `date` date)
;
INSERT INTO articles
(`id`, `date`)
VALUES
(1, '2016-01-01'),
(2, '2017-01-01'),
(3, '2018-01-01')
;
CREATE TABLE users
(`id` int, `date` date)
;
INSERT INTO users
(`id`, `date`)
VALUES
(1, NULL),
(2, NULL)
;
CREATE TABLE t2_upper
(`id` int, `key` varchar(7), `value` varchar(6))
;
INSERT INTO t2_upper
(`id`, `key`, `value`)
VALUES
(1, 'title', 'title1'),
(1, 'user_id', '1'),
(2, 'title', 'title2'),
(2, 'user_id', '2'),
(3, 'title', 'title3'),
(3, 'user_id', '1')
;
CREATE TABLE t2_lower
(`id` int, `key` varchar(4), `value` varchar(5))
;
INSERT INTO t2_lower
(`id`, `key`, `value`)
VALUES
(1, 'name', 'user1'),
(2, 'name', 'user2')
;
Query 1:
select a.id, tn.value article_title, a.date, tu.id user_id, u.value user_name
from articles a
inner join (
select
*
from t2_upper
where `key` = 'title'
) tn on a.id = tn.id
inner join (
select
*
from t2_upper
where `key` = 'user_id'
) tu on a.id = tu.id
inner join (
select
*
from t2_lower
where `key` = 'name'
) u on tu.value = u.id
Results:
| id | article_title | date | user_id | user_name |
|----|---------------|------------|---------|-----------|
| 1 | title1 | 2016-01-01 | 1 | user1 |
| 2 | title2 | 2017-01-01 | 2 | user2 |
| 3 | title3 | 2018-01-01 | 3 | user1 |

MYSQL select recent record of each from

See my table(sample_table),
-----------------------------
id | from | to |
-----------------------------
1 | 2 | 1 |
3 | 2 | 1 |
4 | 2 | 4 |
5 | 3 | 2 |
9 | 3 | 1 |
11 | 4 | 1 |
12 | 4 | 3 |
-----------------------------
For each from, I would like the row holding the most recent to, where to = 1
I mean I want only following,
-----------------------------
id | from | to |
-----------------------------
3 | 2 | 1 |
9 | 3 | 1 |
11 | 4 | 1 |
-----------------------------
I Try following Query,
SELECT * FROM sample_table WHERE to = 1 GROUP BY from
It's giving first row of each. Help me.
Thanks,
There are many ways to do it and here is one way
select t1.* from sample_table t1
join(
select max(id) as id,`from` from
sample_table where `to` = 1
group by `from`
)t2
on t1.id= t2.id and t1.`from` = t2.`from`
https://dev.mysql.com/doc/refman/5.0/en/example-maximum-column-group-row.html
Try this
select t1.id, t1.from, t1.to from table as t1 inner join
(
select to, from,min(id) as id from table
where to=1
group by to,from
) as t2
on t1.to=t2.to and t1.id=2.id and t1.from=t2.from

MySQL query to order by parent then child places

I have a table of pages in my database, each page can have a parent as below:
id parent_id title
1 0 Home
2 0 Sitemap
3 0 Products
4 3 Product 1
5 3 Product 2
6 4 Product 1 Review Page
What would be the best MySQL query to select all pages ordered by parent then child then child again if there is more than one level, there will be a maximum of three levels. The above example would produce the desired order:
Home
Sitemap
Products
Product 1
Product 1 Review Page
Product 2
If you have to stick with your model, i suggest this query:
SELECT p.id, p.title,
(
SELECT LPAD(parent.id, 5, '0')
FROM page parent
WHERE parent.id = p.id AND parent.parent_id = 0
UNION
SELECT CONCAT(LPAD(parent.id, 5, '0'), '.', LPAD(child.id, 5, '0'))
FROM page parent
INNER JOIN page child ON (parent.id = child.parent_id)
WHERE child.id = p.id AND parent.parent_id = 0
UNION
SELECT CONCAT(LPAD(parent.id, 5, '0'), '.', LPAD(child.id, 5, '0'), '.', LPAD(grandchild.id, 5, '0'))
FROM page parent
INNER JOIN page child ON (parent.id = child.parent_id)
INNER JOIN page grandchild ON (child.id = grandchild.parent_id)
WHERE grandchild.id = p.id AND parent.parent_id = 0
) AS level
FROM page p
ORDER BY level;
Example of result set:
+-----+-------------------------+-------------------+
| id | title | level |
+-----+-------------------------+-------------------+
| 1 | Home | 00001 |
| 2 | Sitemap | 00002 |
| 3 | Products | 00003 |
| 4 | Product 1 | 00003.00004 |
| 6 | Product 1 Review Page 1 | 00003.00004.00006 |
| 646 | Product 1 Review Page 2 | 00003.00004.00646 |
| 5 | Product 2 | 00003.00005 |
| 644 | Product 3 | 00003.00644 |
| 645 | Product 4 | 00003.00645 |
+-----+-------------------------+-------------------+
9 rows in set (0.01 sec)
Output of EXPLAIN:
+------+--------------------+--------------+--------+---------------+---------+---------+--------------------------+------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+--------------------+--------------+--------+---------------+---------+---------+--------------------------+------+----------------+
| 1 | PRIMARY | p | ALL | NULL | NULL | NULL | NULL | 441 | Using filesort |
| 2 | DEPENDENT SUBQUERY | parent | eq_ref | PRIMARY,idx1 | PRIMARY | 4 | tmp.p.id | 1 | Using where |
| 3 | DEPENDENT UNION | child | eq_ref | PRIMARY,idx1 | PRIMARY | 4 | tmp.p.id | 1 | |
| 3 | DEPENDENT UNION | parent | eq_ref | PRIMARY,idx1 | PRIMARY | 4 | tmp.child.parent_id | 1 | Using where |
| 4 | DEPENDENT UNION | grandchild | eq_ref | PRIMARY,idx1 | PRIMARY | 4 | tmp.p.id | 1 | |
| 4 | DEPENDENT UNION | child | eq_ref | PRIMARY,idx1 | PRIMARY | 4 | tmp.grandchild.parent_id | 1 | |
| 4 | DEPENDENT UNION | parent | eq_ref | PRIMARY,idx1 | PRIMARY | 4 | tmp.child.parent_id | 1 | Using where |
| NULL | UNION RESULT | <union2,3,4> | ALL | NULL | NULL | NULL | NULL | NULL | |
+------+--------------------+--------------+--------+---------------+---------+---------+--------------------------+------+----------------+
8 rows in set (0.00 sec)
I used this table layout:
CREATE TABLE `page` (
`id` int(11) NOT NULL,
`parent_id` int(11) NOT NULL,
`title` varchar(255) default NULL,
PRIMARY KEY (`id`),
KEY `idx1` (`parent_id`)
);
Note that I included an index on parent_id to improve performance.
I think you should put one more field in your table, called level and store in it the level of the node, and then sort your query by level then by parent.
If you have some control over the table schema, you may want to consider using a nested set representation instead. Mike Hillyer wrote an article on this:
Managing Hierarchical Data in MySQL
work smarter not harder:
SELECT menu_name , CONCAT_WS('_', level3, level2, level1) as level FROM (SELECT
t1.menu_name as menu_name ,
t3.sorting AS level3,
t2.sorting AS level2,
t1.sorting AS level1
FROM
en_menu_items as t1
LEFT JOIN
en_menu_items as t2
on
t1.parent_id = t2.id
LEFT JOIN
en_menu_items as t3
on
t2.parent_id = t3.id
) as depth_table
ORDER BY
level
that is it..
Ugh. Queries like this involving trees are annoying and generally, if you want it to be scalable to any number of levels, you won't do it with a single query, you'll use a few building up the tree at each level.
Well, you can always get it all in one query and process it in PHP. That would be probably the simplier way to get a tree.

Categories