I have a table for categories. This has a recursive relationship so that a category can become a subcategory of another category. The table looks like this:
id name short_desc long_desc tag_id parent_id
I wrote simple to get sql to find all level 1 categories:
SELECT * FROM category WHERE parent_id =0
Then I wrote a query to get all of the level 2 categories (where parent category doesn't have a parent)
SELECT * FROM category WHERE parent_id IN (SELECT id FROM category WHERE parent_id =0)
What I would like to do, is produce a column where is shows all category data and any relevant parent category.
Logically like this:
select all from category
if parent_id != 0, add the parent as a new row
repeat 2 until all parents have been accounted for.
The result should look something like this:
id name short_desc long_desc tag_id parent_name parent_name_2
if the parent_name is null / empty, then parent_name should remain empty. if there is a parent_name id in the field, then check to see if there is a parent_name_2 and if so, populate both columns, if not then only populate parent_name.
I do have the option of coding this in jquery or php which I have a good idea how to do. However, I am sure that I can get the data I need from a good SQL query.
Any help would be greatly appreciated.
Kind Regards
Nick
Here's one option using multiple outer joins:
select c.*,
case when c2.id is not null then c2.name end parent_name,
case when c3.id is not null then c3.name end parent_name_2
from category c
left join category c2 on c.parent_id = c2.id
left join category c3 on c2.parent_id = c3.id
SQL Fiddle Demo
Related
I am working on an application. where I have a Table:-
Category(Category_ID,CategoryName,Parent,Category_Tag)
In this table Category_ID and Parent of type bigint and CategoryName and Category_Tag are of nvarchar. I want to select all CategoryName from Category table with its Name and Parent Name also. If any Category does not have any Parent then the query should return '-'
I have used following sql query:
SELECT Category_ID, Category_Name, Parent, Category_Tag FROM Category
But dows not getting the desired result.Please help me.
If you need only ONE level parent category then use LEFT JOIN
SELECT a.Category_ID, a.Category_Name, a.Parent, a.Category_Tag,
ISNULL(b.Category_Name,'-') as Parent_Name
FROM Category as a
LEFT JOIN Category as b on (a.Parent=b.Category_ID)
If you want the empty parent to be replaced with '-', use ISNULL
SELECT Category_ID, Category_Name, ISNULL(convert(varchar(20),Parent), '-') as Parent, Category_Tag FROM Category
I have a table in database for categories and sub categories. Its internal structure is:
id int not null primary
name text
subcatfrom int
it contains some of rows for categories and its sub categories. I want "SELECT" sql command to fetch categories and grouping their sub categories after it for every root category as following for example :
-cat1
--subcat1
--subcat2
-cat2
--subcat1
--subcat2
is it possible ?
The original question wants the subcategories on separate rows. Here is one way:
select name
from ((select category as name, 1 as iscat, category as sortorder
from t
) union all
(select tsub.category as name 0 as iscat, t.category as sortorder
from t join
tsub on
on t.subcategory_id = s.category_id
)
) a
where not exists (select 1 from category c where c.subcategory_id = a.sortorder limit 1)
order by sortorder, iscat desc, name
What is this doing? The inner union all is bringing together all categories and subcategories. It is assigning what you want in the table as well as information for sorting. The overall ordering is by "parent" category name.
The where clause is limiting this data to categories that are not the subcategory of anything else -- the top level categories.
I am making the assumptions that-
1. you have just one level of parent child relationship. ie subcategory can't have further sub-category
2. For top level category, value of subcatfrom is 0
SELECT * FROM
(
SELECT NAME AS parent_category_name, '' AS child_category_name FROM categories WHERE subcatfrom = 0
UNION
SELECT b.NAME AS parent_category_name, a.NAME AS child_category_name FROM categories a JOIN categories b ON a.subcatfrom = b.id
) a ORDER BY a.parent_category_name, a.child_category_name;
That's very easy but with this structure
Table: category_id , name , parent_id
Sample Data
category_id name parent_id
1 A 0
2 B 0
3 C 1
4 D 1
This means A is a category which has 2 subcategories C and D. And parent_id 0 means it is a parent category
Now the sql is
SELECT lc.category_id,
lc.name,
rc.subcategories
FROM categories
LEFT JOIN (
SELECT
subcategory_id ,
GROUP_CONCAT(name) AS subcategories
FROM categories) AS rc
ON lc.category_id = rc.parent_id
This will give you the following result
category_id name subcategories
1 A C,D
2 B (null)
I have a mysql table named "category". the basic structure looks like this-
------ -------- ------
cat_id cat_name parent
------ -------- ------
1 test1 NULL
2 test2 NULL
3 test3 2
4 test4 1
5 test5 3
now i want all the category data with parent category name (not only id) in a single query. is that possible? i could do it by using a second query (getting child's parent name) in a while loop and merging data as a whole. but is it possible to do this with a single query?
Join the table with itself, using the parent column to link to the cat_id of the parent.
SELECT c1.cat_id as childID, c1.cat_name ChildName, c2.cat_name as ParentName
from category c1
LEFT OUTER JOIN category c2
ON c1.parent = c2.cat_id
Be careful: since some elements have no parents (NULL), I put a LEFT
OUTER JOIN so those rows are displayed as well. If you don't want
that, use a JOIN instead of LEFT OUTER JOIN.
You can also show the lines, but display something else (empty or a
text or ...) instead of the NULL by using COALESCE.
You can consider the result as one (big) new table, so you can add WHERE clauses as you usually do, for example filtering on the parent name: WHERE c2.cat_name = 'test2'
Select p.cat_id, p.cat_name, c.cat_id, c.cat_name, c.parent
From category Left Join category On p.cat_id = c.parent
Where p.cat_name = 'name'
SELECT c1.category_name AS category, c2. category_name AS sub_category
FROM (
SELECT *
FROM category
) AS c1
INNER JOIN (
SELECT *
FROM category
) AS c2 ON c1.category_id = c2.category_id
I have a MYSQL table called 'categories' from a project I inherited from someone else.
id parent_id name
1 NULL Travel
2 NULL Sleep
3 NULL Eat
4 NULL Bath
5 1 Prams
6 1 Travel Systems
7 2 Cots
8 3 High Chairs
The table is obviously a lot bigger than that, but you get the general idea. I have a MYSQL statement which brings together this table with other category, brand and product tables, but basically I want to list the parent category name from the above table with the sub-category in the statement. How do I do this?
My current statement is something like:
SELECT brands.name, products.name, categories.id, categories.name, brands.id,
FROM `products` , `brands` , `categories`
WHERE products.brand_id = brands.id
AND products.category_id = categories.id
AND brands.name = '$brand'
ORDER BY categories.name, products.name
How do I retrieve the parent category names in the results?
For example if the product is a Pram, how can I output "Travel". I could do seperate MYSQL statements in the loop but I want to avoid this. This is either a stupidly simple question (in which case I apologise for being brain dead) or a little more complicated! Thanks.
First you need to know the parent id of the current category and then get the name for that id, you could use a subquery in this way:
SELECT name FROM categories WHERE id = (SELECT pid FROM categories WHERE name = $brand)
EDIT: Since you need to get the category and subcategory names in the same row for a given subcategory id, try this:
SELECT sc.name AS subcategory, c.name AS category
FROM categories sc
LEFT JOIN categories c ON c.id = sc.parent
WHERE sc.id = $subcategory_id
I got an existing products database which I'm writing an administration tool for (in PHP).
The database contains the following "categories" table:
Table Categories
--------------------
PK | id
FK | parent_id
| title
Now the foreign key "parent_id" contains an id taken from the same table, or "0" if it's a topmost category.
For creating an overview I now need a mysql statement which results in the following data:
id | parent_id | title | parent_title
The parent_title is where I've no idea. I created the following statement:
SELECT
c1.id,
c1.parent_id,
c1.title,
c2.title as `parent_title`
FROM
categories c1,
categories c2
WHERE
c1.parent_id = c2.id
I now only get all categories which have got a parent category.
Should be simple, and might have already been answered here. I think I only didn't find the right words to search for to find it by searching existing articles.
Thanks for your help,
Daniel
You can use a LEFT OUTER JOIN for this:
SELECT c1.id,
c1.parent_id,
c1.title,
c2.title as `parent_title`
FROM categories c1
left outer join categories c2 on c1.parent_id = c2.id
you're looking for an OUTER JOIN :)
See here: http://www.quackit.com/sql/tutorial/sql_outer_join.cfm