Mysql
 sql >> Base de données >  >> RDS >> Mysql

MySQL :comment interroger parent-enfant ?

Voici une idée. Mais il est basé sur de nombreuses hypothèses sur la façon dont vos données sont configurées. ID toujours croissants dans l'arborescence, seulement deux niveaux, etc.

SELECT f.foo_id,f.foo_parent_id FROM foo f
foo f

--donnez-moi le nombre X supérieur de parent_ids(C'est bien, vous ajustez simplement la LIMITE de 10 pour faire varier le nombre de niveaux parents à afficher)

INNER JOIN 
(select foo_id from foo where foo_parent_id is null order by foo_parent_id 
LIMIT 10
) top_foo_parent
      on isnull(f.foo_parent_id,f.foo_id) = top_foo_parent.foo_id
WHERE

(Cette partie est un peu hacky, car vous devez en mettre une chaîne de plus en plus longue pour dépasser deux enfants)

--c'est le premier enfant, ou...

(f.foo_id in (select MIN(foo_id) from foo fc1 where fc1.foo_parent_id =f.foo_parent_id)
 )
 or

--c'est le deuxième enfant, ou...

(f.foo_id in (select MIN(foo_id) from foo fc1 where fc1.foo_parent_id =f.foo_parent_id  and fc1.foo_id not in (select MIN(foo_id) from foo fc2 where fc2.foo_parent_id=f.foo_parent_id))
 )
 or 

--c'est le parent

 f.foo_parent_id is null
order by isnull(f.foo_parent_id,f.foo_id)*100 + f.foo_id

Donc, ce que nous faisons ici consiste essentiellement à ordonner par la colonne parent_id, puis les colonnes enfants en dessous avec une légère torsion. Si la colonne parentid est NULL, nous utilisons l'ID réel. Cela signifie qu'à des fins de commande, notre tableau ressemble à ceci :

==============================================================================
| foo_id | foo_parent_id |   isnull(f.foo_parent_id,f.foo_id)
==============================================================================
| 1      | NULL           |         (1)
| 2      | NULL           |         (2)
| 3      |  1             |         1
| 4      |  2             |         2
| 5      |  1             |         1
| 7      |  2             |         2
----------------------------------------------------------------------

Ensuite, nous multiplions cette colonne de commande *100

==============================================================================
| foo_id | foo_parent_id |   isnull(f.foo_parent_id,f.foo_id)*100
==============================================================================
| 1      | NULL           |         100
| 2      | NULL           |         200
| 3      |  1             |         100
| 4      |  2             |         200
| 5      |  1             |         100
| 7      |  2             |         200
----------------------------------------------------------------------

et enfin nous y ajoutons notre colonne foo_id

==============================================================================
| foo_id | foo_parent_id |   isnull(f.foo_parent_id,f.foo_id)*100 + foo_id
==============================================================================
| 1      | NULL           |         101
| 2      | NULL           |         202
| 3      |  1             |         103
| 4      |  2             |         204
| 5      |  1             |         105
| 7      |  2             |         207
----------------------------------------------------------------------

Maintenant, nous ordonnons la table par cette colonne virtuelle et...

==============================================================================
| foo_id | foo_parent_id |   ORDER BY isnull(f.foo_parent_id,f.foo_id)*100 + foo_id
==============================================================================
| 1      | NULL           |         101
| 3      |  1             |         103
| 5      |  1             |         105
| 2      | NULL           |         202    
| 4      |  2             |         204
| 7      |  2             |         207
----------------------------------------------------------------------

C'est parti !