I have this tag table,
tag_id tag_name parent_id cat_id
3 Tagname-1 NULL NULL
5 tagname-2 NULL NULL
6 tagname-3 NULL NULL
9 tagname-4 NULL NULL
11 tagname-5 3 NULL
13 tagname-6 3 NULL
15 tagname-8 5 NULL
17 tagname-9 5 NULL
18 tagname-10 NULL NULL
20 tagname-11 6 NULL
22 tagname-12 9 NULL
24 tagname-13 NULL NULL
26 tagname-14 NULL NULL
28 tagname-15 NULL NULL
I want to return a result like this,
ParentID ParentName TotalChildren
3 Tagname-1 2
5 tagname-2 2
6 tagname-3 1
9 tagname-4 1
18 tagname-10 0
24 tagname-13 0
26 tagname-14 0
28 tagname-15 0
So here the query I came out with so far,
SELECT
a.tag_id as ParentID,
a.tag_name as ParentName,
b.TotalChildren
FROM root_tags a INNER JOIN
(
SELECT parent_id, COUNT(1) as TotalChildren
FROM root_tags
WHERE parent_id <> tag_id
GROUP BY parent_id
) b
ON a.tag_id = b.parent_id
ORDER BY ParentID
But, unfortunately, it only return the result like this,
ParentID ParentName TotalChildren
3 Tagname-1 2
5 tagname-2 2
6 tagname-3 1
9 tagname-4 1
Which means it is missing the parents without any children.
How can I make the tags without children to become parents too? or in other words, how to make the tags without parents to become parents themselves?
EDIT:
SELECT
a.tag_id as ParentID,
a.tag_name as ParentName,
b.TotalChildren
FROM root_tags a LEFT OUTER JOIN
(
SELECT parent_id, COUNT(1) as TotalChildren
FROM root_tags
WHERE parent_id <> tag_id
GROUP BY parent_id
) b
ON a.tag_id = b.parent_id
ORDER BY ParentID
the answer above returns,
ParentID ParentName TotalChildren
3 Tagname-1 2
5 tagname-2 2
6 tagname-3 1
9 tagname-4 1
11 tagname-5 NULL
13 tagname-6 NULL
15 tagname-8 NULL
17 tagname-9 NULL
18 tagname-10 NULL
20 tagname-11 NULL
22 t开发者_高级运维agname-12 NULL
24 tagname-13 NULL
26 tagname-14 NULL
28 tagname-15 NULL
which is incorrect as it returns all the children.
You're nearly there.. just need to make the join an outer one:
EDITED:
SELECT
a.tag_id as ParentID,
a.tag_name as ParentName,
b.TotalChildren
FROM root_tags a LEFT OUTER JOIN
(
SELECT parent_id, COUNT(1) as TotalChildren
FROM root_tags
WHERE parent_id <> tag_id
GROUP BY parent_id
) b
ON a.tag_id = b.parent_id
WHERE b.TotalChildren is not null
ORDER BY ParentID
Prefer a Join against a Subquery:
SELECT parents.tag_id AS ParentID,
parents.tag_name AS ParentName,
COUNT(childs.tag_id) AS TotalChildren
FROM root_tags AS parents
LEFT OUTER JOIN root_tags AS childs
ON parents.tag_id = childs.parent_id
WHERE parents.parent_id IS NULL
GROUP BY parents.tag_id, parents.tag_name
ORDER BY parents.tag_id
I don't completely understand your requirement here, but I'll say that if you change the inner join to a left join and b.TotalChildren
to IF(b.TotalChildren is null, 0, b.TotalChildren)
then you'll get the result set you desire.
SELECT
a.tag_id as ParentID,
a.tag_name as ParentName,
count(b.child) as TotalChildren
FROM root_tags as a INNER JOIN
(
SELECT parent_id as child FROM root_tags
WHERE parent_id is not NULL
) as b
ON a.tag_id = b.child
where a.parent_id is NULL
ORDER BY ParentID
精彩评论