2009-12-29 9 views
41

¿Hay alguna forma de especificar el campo de consulta padre desde una subconsulta en mySQL?¿Cómo se especifica el campo de consulta principal desde una subconsulta en mySQL?

Por ejemplo:
He escrito un programa básico de tipo tablón de anuncios en PHP.

En la base de datos, cada publicación contiene: id (PK) y parent_id (la identificación de la publicación principal). Si la publicación es en sí misma una primaria, entonces parent_id está establecida en 0.

Estoy tratando de escribir una consulta mySQL que encuentre todas las publicaciones principales y la cantidad de hijos que tenga la matriz.

$query = "SELECT id, (
     SELECT COUNT(1) 
     FROM post_table 
     WHERE parent_id = id 
) as num_children 
FROM post_table 
WHERE parent_id = 0"; 

La parte difícil es que la primera Identificación no sabe que debería estar refiriéndose a la segunda Identificación que se encuentra fuera de la subconsulta. Sé que puedo hacer SELECCIONAR ID AS id_tmp y luego referirme a él dentro de la subconsulta, pero luego si también quiero devolver la identificación y mantener "id" como el nombre de la columna, entonces tendría que hacer una consulta que me devuelva me 2 columnas con los mismos datos (que parece complicado para mí)

$query = "SELECT id, id AS id_tmp, 
      (SELECT COUNT(1) 
      FROM post_table 
      WHERE parent_id = id_tmp) as num_children 
     FROM post_table 
     WHERE parent_id = 0"; 

la forma desordenada funciona bien, pero siento una oportunidad para aprender algo aquí, así que pensé que había puesto la cuestión.

Respuesta

60

Cómo sobre: ​​

$query = "SELECT p1.id, 
       (SELECT COUNT(1) 
        FROM post_table p2 
        WHERE p2.parent_id = p1.id) as num_children 
      FROM post_table p1 
      WHERE p1.parent_id = 0"; 

o si se pone un alias en el p1.id, se podría decir:

$query = "SELECT p1.id as p1_id, 
       (SELECT COUNT(1) 
        FROM post_table p2 
        WHERE p2.parent_id = p1.id) as num_children 
      FROM post_table p1 
      WHERE p1.parent_id = 0"; 
+0

¿Qué ocurre si tomé alias para p1.id? –

+0

¿Qué significa eso? "tomado alias para"? – Don

+0

Si he tomado alias como: "SELECT p1.id como MYID", ¿cuál será la consulta? –

2

dar los nombres de las tablas únicas:

$query = "SELECT a.id, (SELECT COUNT(1) FROM post_table b WHERE parent_id = a.id) as num_children FROM post_table a WHERE a.parent_id = 0"; 
4

Puede intentar algo como esto

SELECT pt.id, 
     CountTable.Cnt 
FROM post_table pt LEFT JOIN 
     (
      SELECT parent_id, 
        COUNT(1) Cnt 
      FROM post_table 
      WHERE parent_id <> 0 
      GROUP BY parent_id 
     ) CountTable ON pt.id = CountTable.parent_id 
WHERE pt.parent_id = 0 

Para volver a su ejemplo, utilice el alias de la mesa principal en la sub seleccione

SELECT pt.id, 
     (SELECT COUNT(1) FROM post_table WHERE parent_id = pt.id) 
FROM post_table pt 
WHERE pt.parent_id = 0 
0

La siguiente sintaxis funciona en Oracle. ¿Puedes probar si lo mismo funciona en MYSQL también? Se llama subconsulta escalar en Oracle.

Solo necesita aliar las dos tablas de manera diferente para distinguirlas si usa la misma tabla dos veces.

sql> select empno, 
    2   (select dname from dept where deptno = emp.deptno) dname 
    3 from emp 
    4 where empno = 7369; 

    EMPNO DNAME 
---------- -------------- 
     7369 RESEARCH 

sql> select parent.empno, 
    2   (select mgr from emp where empno = parent.empno) mgr 
    3 from emp parent 
    4 where empno = 7876; 

    EMPNO  MGR 
---------- ---------- 
     7876  7788 
0

Gracias Don. Tenía una consulta anidada como se muestra a continuación y una cláusula WHERE en la que no se pudo determinar el alias v1. Aquí está el código que no está trabajando:

Select 
    teamid, 
    teamname 
FROM 
    team as t1 
INNER JOIN (
    SELECT 
     venue_id, 
     venue_scores, 
     venue_name 
    FROM venue 
    WHERE venue_scores = (
     SELECT 
      MAX(venue_scores) 
     FROM venue as v2 
     WHERE v2.venue_id = v1.venue_id  /* this where clause wasn't working */ 
    ) as v1 /* v1 alias already present here */ 
); 

Por lo tanto, me acaba de agregar el alias v1 de nuevo dentro de la JOIN. Lo cual lo hizo funcionar.

Select 
    teamid, 
    teamname 
FROM 
    team as t1 
INNER JOIN (
    SELECT 
     venue_id, 
     venue_scores, 
     venue_name 
    FROM venue as v1    /* added alias v1 here again */ 
    WHERE venue_scores = (
     SELECT 
      MAX(venue_scores) 
     FROM venue as v2 
     WHERE v2.venue_id = v1.venue_id /* Now this works!! */ 
    ) as v1  /* v1 alias already present here */ 
); 

Espero que esto sea útil para alguien.

Cuestiones relacionadas