简体   繁体   中英

How to select all matching rows from three tables by join query

I need to create a vertical menu by joining three mysql tables.

This is the normal menu should like.

Main Cat Items 1 -> Categories 1 --> Sub Cat Items 1 
                    Categories 1 --> Sub Cat Items 2
                    Categories 2 --> Sub Cat Items 3
                    Categories 3 --> Sub Cat Items 4

Main Cat Items 2 -> Categories 4 --> Sub Cat Items 5

These are the three tables I have Table : Main_cat

+-------------+---------------+
| main_cat_id | main_cat_name |
+-------------+---------------+
|           1 | main cat 1    |
|           2 | main cat 2    |
|           3 | main cat 3    |
+-------------+---------------+

Table : Categories

+--------+-------------+----------------+
| cat_id | main_cat_id | cat_name       |
+--------+-------------+----------------+
|      1 |           1 | cat1 parent 1  |
|      4 |           1 | cat2 parent 1  |
|      5 |           1 | cat3 parent 1  |
|      6 |           2 | cat 4 parent 2 |
|      7 |           2 | cat 5 parent 2 |
|      8 |           3 | cat 6 parent 3 |
+--------+-------------+----------------+

Table : Sub_cat

+------------+-------------+--------+----------------------+
| sub_cat_id | main_cat_id | cat_id | sub_cat_name         |
+------------+-------------+--------+----------------------+
|          1 |           1 |      1 | sub 1 cat1 parent 1  |
|          2 |           1 |      1 | sub 2 cat1 parent 1  |
|          3 |           1 |      4 | sub 3 cat 4 parent 1 |
+------------+-------------+--------+----------------------+

Every time I tried I am getting only an array having some fields but what I am expecting is a malty dimensional array. these are the queries I tried.

this is one of a array I am getting by one of following query.

Array
(
    [0] => stdClass Object
        (
            [main_cat_name] => main cat 1
            [main_cat_id] => 1
            [main_cat_url] => 
            [cat_id] => 1
            [cat_name] => cat1 parent 1
            [cat_url] => 
            [sub_cat_id] => 1
            [sub_cat_name] => sub 1 cat1 parent 1
            [sub_cat_url] => 
        )

    [1] => stdClass Object
        (
            [main_cat_name] => main cat 2
            [main_cat_id] => 2
            [main_cat_url] => 
            [cat_id] => 
            [cat_name] => 
            [cat_url] => 
            [sub_cat_id] => 
            [sub_cat_name] => 
            [sub_cat_url] => 
        )

    [2] => stdClass Object
        (
            [main_cat_name] => main cat 3
            [main_cat_id] => 3
            [main_cat_url] => 
            [cat_id] => 
            [cat_name] => 
            [cat_url] => 
            [sub_cat_id] => 
            [sub_cat_name] => 
            [sub_cat_url] => 
        )

)



$query = "SELECT "
                . "mc.main_cat_name, mc.main_cat_url, cg.cat_name, cg.cat_url,                      sc.sub_cat_name, sc.sub_cat_url "
                . "FROM"
                . " main_cat AS mc "
                . "LEFT JOIN "
                . "categories AS cg "
                . "ON "
                . "mc.main_cat_id = cg.main_cat_id "
                . "LEFT JOIN "
                . "sub_cat AS sc "
                . "ON "
                . "cg.cat_id = sc.sub_cat_id ";

$query = "SELECT "
                . "mc.main_cat_name, mc.main_cat_id, mc.main_cat_url, cg.cat_id, cg.cat_name, cg.cat_url, sc.sub_cat_id, sc.sub_cat_name, sc.sub_cat_url "
                . "FROM"
                . " main_cat AS mc "
                . "LEFT JOIN "
                . "sub_cat AS sc "
                . "ON "
                . "sc.main_cat_id = mc.main_cat_id "
                . "LEFT JOIN "
                . "categories AS cg "
                . "ON "
                . "cg.cat_id = sc.cat_id "
                . "GROUP BY "
                . "main_cat_id";



$query = "SELECT "
            . "* "
            . "FROM "
            . "main_cat mc "
            . "LEFT JOIN sub_cat sc "
            . "ON sc.main_cat_id = mc.main_cat_id "
            . "LEFT JOIN categories cg "
            . "ON "
            . "cg.cat_id = sc.cat_id "
            . "Group BY "
            . "sc.cat_id, sc.main_cat_id";

But non of these queries give me what I am expecting. can you help me on this.

The query that comes closest is:

select mc.main_cat_name, c.cat_name, sc.sub_cat_name
from main_cat mc left join
     categories c
     on c.main_cat_id = mc.main_cat_id left join
     sub_cat sc
     on sc.cat_id = c.cat_id 
order by mc.main_cat_id, c.cat_id, sc.sub_cat_id;

This will, however, give you "relational" results with each cell filled in. More like:

Main Cat Items 1 -> Categories 1 --> Sub Cat Items 1 
Main Cat Items 1 -> Categories 1 --> Sub Cat Items 2
Main Cat Items 1 -> Categories 2 --> Sub Cat Items 3
Main Cat Items 1 -> Categories 3 --> Sub Cat Items 4
Main Cat Items 2 -> Categories 4 --> Sub Cat Items 5

If you want to remove the duplicated names for presentation, then you should do that in the application. It is possible to do this transformation in the database. However, normally result sets from SQL queries are tables, meaning that ordering is unimportant. In this case, ordering is critical, because otherwise you will not know the correct main category for the second, third, and fourth rows.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM