2011-06-04 9 views
8

Sé que esta pregunta aparece a menudo, pero hoy no puedo encontrar la respuesta que estoy buscando. Tengo una tabla con este esquema.Seleccione Parent and Children With MySQL

CREATE TABLE `comments` (
    `id` bigint(10) unsigned not null auto_increment, 
    `parent_id` bigint(10) unsigned default 0, 
    `date_sent` datetime not null, 
    `content` text not null, 
    PRIMARY KEY(`id`) 
) ENGINE=InnoDB; 

Me gustaría seleccionar las filas primarias y las secundarias de esas filas. No permito que los niños tengan hijos, por lo que es solo uno de los padres, con cualquier número de hijos.

Creo que he visto esto hecho con uniones antes, o uniones internas.

Respuesta

23

Los padres son los registros sin parent_id.
Los niños tienen parent_id igual al comentario del padre id.

SELECT ... 
    FROM comments AS parent 
     LEFT JOIN comments AS child 
     ON child.parent_id = parent.id 
    WHERE parent.parent_id IS NULL 
ORDER BY parent.id, child.id; 

Tenga en cuenta que la autocombinación debe ser una unión externa para que no se pierda los comentarios de los padres sin hijos.

+0

+1. Eché de menos que él podría querer encontrar filas sin padres – a1ex07

+0

Gracias, a1ex07.Creo que quisiste decir comentarios de padres sin hijos ;-) Creo que también deberías agregar a tu cláusula 'WHERE':' p.parent_id IS NULL'. Aclamaciones. – bernie

+2

¿Qué sucede si tengo hijos para hijos? ¿No necesitaría tener varias uniones? – Dejell

3

¿Está buscando

SELECT p.id, child.* 
FROM comments p 
INNER JOIN comments child ON (child.parent_id = p.id) 
WHERE .... 

ACTUALIZACIÓN
O LEFT JOIN si quieres ver filas sin padres

+2

Qué pasa si tengo del niño para los childs? ¿No necesitaría tener varias uniones? – Dejell

+0

¿Cómo resuelves el problema de muchos niños a niños? –

+0

Quiero limitar la búsqueda de padres. cómo puedo ponerle límite – Adrian

2

no he diciendo exactamente, creo que su conseguir este tipo de problema de la siguiente manera como:

Ordered_Item

ID | Item_Name 
1 | Pizza 
2 | Stromboli 

Ordered_Options

Ordered_Item_ID | Option_Number | Value 
     1    43   Pepperoni 
     1    44   Extra Cheese 
     2    44   Extra Cheese 

salida

ID | Item_Name | Option_1 | Option_2 
1 Pizza  Pepperoni Extra Cheese 
2 Stromboli  NULL  Extra Cheese 

Y los mis sugerencias para utilizar este método resolver este problema, ya que después de como:

  1. La forma más fácil sería hacer uso del grupo GROUP_CONCAT función aquí ..
select 
     ordered_item.id as `Id`, 
     ordered_item.Item_Name as `ItemName`, 

    GROUP_CONCAT(Ordered_Options.Value) as `Options` 

    from ordered_item, ordered_options 

    where ordered_item.id=ordered_options.ordered_item_id 

    group by ordered_item.id 

Qué seria:

Id    ItemName  Options 
1    Pizza   Pepperoni,Extra Cheese 
2    Stromboli  Extra Cheese 

De esta forma puede tener tantas opciones como desee sin tener que modificar su consulta.

Ah, si usted ve los resultados siendo recortado, puede aumentar el límite de tamaño de GROUP_CONCAT así:

SET SESSION group_concat_max_len = 8192; 
Cuestiones relacionadas