У меня есть таблица тегов,
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
Я хочу вернуть такой результат,
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
Итак, вот запрос, с которым я вышел до сих пор,
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
Но, к сожалению, он возвращает результат таким образом,
ParentID ParentName TotalChildren 3 Tagname-1 2 5 tagname-2 2 6 tagname-3 1 9 tagname-4 1
Это означает, что у родителей нет детей без детей.
Как я могу сделать теги без детей, чтобы стать родителями? или, другими словами, как сделать теги без родителей самими родителями?
РЕДАКТИРОВАТЬ:
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
ответ выше возвращается,
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 tagname-12 NULL 24 tagname-13 NULL 26 tagname-14 NULL 28 tagname-15 NULL
который является неправильным, поскольку он возвращает всех детей.
Предпочитают соединение с подзапросом:
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
Вы почти там .. просто нужно сделать соединение внешним:
Редакция:
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
Я не совсем понимаю ваше требование здесь, но я скажу, что если вы измените внутреннее соединение на левое соединение и b.TotalChildren
на IF(b.TotalChildren is null, 0, b.TotalChildren)
то вы получите набор результатов, который вы желаете.
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