In my MySQL-Database, I have two tables, one for the projects and one for the categories:
The projects-table looks something like this:
id | project_title | category_id
---|----------------------|------------
1 | My Book Project | 101
2 | My Comic Project | 102
3 | My Magazine Project | 104
Then I have the categories. These can have a parent category which is stored in the same table:
id | category_title | parent_id
---|--------------------|----------
101 | Books | 0
102 | Comics | 101
103 | DVDs | 0
104 | Magazines | 101
I like to fetch all the projects with the according category and (optional) sub-category (if parent_id
is provided). If the category has no sub-category, the sub-category should be something like "-" or "none".
Now I know how I can get all these values with several statements:
First Statement: Fetch the projects with the indicated category (which can be a main-category or a sub category, therefor I fetch also the category's parent_id
):
SELECT
p.project_title,
c.category_title,
c.parent_id as cat_parent_id
FROM
projects p,
categories c
WHERE
p.category_id = c.id
Second Statement(s): After that, I could fetch the possible sub-category of a project within a loop, or assign the found category as main-category, eg with php:
<?php
foreach( $rows as $project ) {
if ( $project['cat_parent_id'] > 0 ) {
$project['sub_category'] = $project['category_title'];
// query main-category here
}
else {
$project['main_category'] = $project['category_title'];
$project['sub_category'] = 'none';
}
// do things with this project ...
}
?>
The problem is that I will have another query for each project found, and this is not nice. I think there should be a way to fetch all the required values in one statement. I found this question on SO which is nearly the same, but in my case, the sub-category is obtional.
As John Cleese would say: Could someone please give me a push?
You can join categories twice:
SELECT
p.project_title,
c.category_title,
COALESCE(c0.category_title, '-')
FROM projects p join categories c on p.category_id = c.id
left join categories c0 on c.parent_id = c0.id;
But it will work only for two levels hierarchy (any category may have zero or one parent).
Accoding to the comments:
SELECT
p.project_title,
COALESCE(c0.category_title, c.category_title),
case when c0.id is not null then c.category_title else '-' end
FROM projects p join categories c on p.category_id = c.id
left join categories c0 on c.parent_id = c0.id;
SELECT
p.project_title,
IF(c2.category_title is null,
c1.category_title,
c2.category_title) as main_category,
IF(c2.category_title is null,
"none",
c1.category_title) as sub_category
FROM projects p
LEFT JOIN categories c1 ON (c1.id = p.category_id)
LEFT JOIN categories c2 ON (c2.id = c1.parent_id)
http://sqlfiddle.com/#!2/85020/1
This returns the requested result:
PROJECT_TITLE MAIN_CATEGORY SUB_CATEGORY
My Book Project Books none
My Comic Project Books Comics
My Magazine Project Books Magazines
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.