2009-03-07 9 views
2

J'ai une table inclinée comme tbltre Table Structure est comme:Compter le nombre d'enfants de la table d'arbre

`id` int(10) unsigned NOT NULL auto_increment, 
`title` longtext NOT NULL, 
`parent` int(10) unsigned default '0' 

Contenu de la table est comme ceci:

id Title parent 
..................... 
    1 abc 0 
    2 xyz 1 
    3 pqr 1 
    4 uuu 2 

Résultats exigés est -

id title no of childs 
........................... 
    1 abc  3 
    2 xyz  1 
    3 pqr  0 
    4 uuu  0 

Répondre

0

Si vous utilisiez Oracle, je suggérerais d'utiliser un CONNECT BY ce qui rendrait cette requête simple.

Vous pourriez être en mesure de faire un groupe par/en ayant un sous-ensemble.

SELECT ID parent_id, TITLE, (
SELECT COUNT(ID) from tbltree group by ID having parent = parent_id) child_count 
FROM tbltree; 

Ceci n'est pas testé et ne fonctionne que pour un niveau profond de l'arborescence.

+0

On dirait que cela a été une demande d'amélioration depuis un certain temps pour mysql – Tom

0

Je n'ai pas pris mon café encore, mais vous pourriez vouloir essayer quelque chose le long des lignes de

select 
    p.id, p.title, count(c.*) 
    from tbltree as c 
    left join tbltree as p 
    where p.id = c.parent 
    group by p.id 
    order by p.id 
+1

Pas de café encore ici non plus, mais qui sent bon. –

+0

Marqué, il voulait les descendants pas les enfants. – Tom

+1

@thaggie Alors (si vous avez raison) il aurait dû utiliser les mots "tous les descendants" et non "enfants" et "enfants" dans la question. SQL je peux faire. Lecture d'esprit, pas tellement. – MarkusQ

1

Que diriez-vous quelque chose comme ça?

SELECT 
    a.id, 
    a.title, 
    COUNT(*) AS children 
FROM 
    tbltree AS a 
    INNER JOIN tbltree AS b ON 
    b.parentid=a.id 
GROUP BY 
    a.id 

Cela ne nécessite qu'une seule autojointure, vous voulez avoir un index sur tbltree.id pour le GROUP BY (probablement vous l'avez comme PRIMAIRE), et un index sur tbltree.parentid pour faire cette adhésion efficace.

+0

Merci, cela a fonctionné pour moi. –

2

Cela devrait vous donner ce que vous voulez EDIT Il n'a pas .... voir la dernière édition ci-dessous:

select 
    parent.id, parent.title, count(child.id) 'number of children' 
from 
    ttt parent left join ttt child 
    on child.parent = parent.id 
group by parent.id 
order by parent.id; 

sortie de MySQL:

+----+-------+--------------------+ 
| id | title | number of children | 
+----+-------+--------------------+ 
| 1 | abc |     2 | 
| 2 | xyz |     1 | 
| 3 | pqr |     0 | 
| 4 | uuu |     0 | 
+----+-------+--------------------+ 

EDIT : Au moins en MySQL, le ORDER BY est superfluous:

Si vous utilisez GROUP BY, les lignes de sortie sont triées en fonction des colonnes GROUP BY comme si vous aviez un ORDER BY pour les mêmes colonnes. Pour éviter le tri supplémentaire que GROUP BY produit, ajoutez ORDER BY NULL

Merci pour le conseil, thomasrutter!

EDIT: Eh bien, thaggie a souligné que je souffre d'un cas de ne pas lire attentivement la question ici. La réponse ci-dessus obtient seulement les enfants d'un parent, pas tous les descendants. Comme d'autres l'ont souligné, si vous utilisez Oracle, vous pouvez utiliser leur syntaxe STARTS WTIH/CONNECT BY. Sinon, this article peut être intéressant.

+0

On dirait que vous, MarcusQ et moi avons obtenu la même réponse à quelques minutes d'intervalle :) J'ai omis l'ORDER BY parce que (au moins dans mysql AFAIK) GROUP BY implique le tri de la même manière. – thomasrutter

+0

Hé, oui. Je suppose que c'est une question classique d'auto-adhésion. Merci pour le conseil sur GROUP BY vs ORDER BY - la documentation MySQL est d'accord avec vous :-) –

+0

Ouais - vous avez tous les deux eu la mauvaise réponse, vérifiez vos résultats par rapport à ce qu'il demande - vous comptez les enfants qu'il veut les descendants . – Tom

0

Espérons que cela résout votre prbolem ...A travaillé pour moi

select F.id as Parent, F.Title ,Count(S.ID) as ChildCount 
from tbltree F 
left outer join tbltree S on F.id = S.Parent 
Group BY F.id ,F.Title 
+1

pourquoi grouper par le titre aussi? ça fait mal. – mauris

Questions connexes