tipos subconsultas consultas complejas anidados anidadas php mysql subquery parent-child

php - subconsultas - tipos de consultas en mysql



¿Cómo especificar el campo de consulta principal desde una subconsulta en mySQL? (5)

¿Hay alguna forma de especificar el campo de consulta principal desde una subconsulta en mySQL?

Por ejemplo:
Escribí 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 un elemento primario, entonces parent_id se establece en 0.

Intento escribir una consulta mySQL que encuentre todas las publicaciones principales y la cantidad de hijos que tenga el padre.

$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 está 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 me parece desordenado)

$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 manera desordenada funciona bien, pero siento la oportunidad de aprender algo aquí, así que pensé en publicar la pregunta.


Dale a las tablas nombres únicos:

$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";


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

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 */ );

Entonces, acabo de agregar el alias v1 nuevamente dentro de 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.


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

Solo necesitaría 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


Podrías probar 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, use el alias de la tabla principal en la selección secundaria

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


Qué tal si:

$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 pones un alias en el p1.id, puedes 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";