2010-04-15 14 views
33

¿Es posible hacer referencia a una consulta externa en una subconsulta con MySQL? Sé que hay algunas casos en que esto sea posible:Hacer referencia a las tablas de la consulta externa en una subconsulta

SELECT * 
FROM table t1 
WHERE t1.date = (
    SELECT MAX(date) 
    FROM table t2 
    WHERE t2.id = t1.id 
); 

pero me pregunto si algo como esto podría funcionar:

SELECT u.username, c._postCount 
FROM User u 
INNER JOIN (
    SELECT p.user, COUNT(*) AS _postCount 
    FROM Posting p 
    --# This is the reference I would need: 
    WHERE p.user = u.id 
    GROUP BY p.user 
) c ON c.user = u.id 
WHERE u.joinDate < '2009-10-10'; 

Sé que podría conseguir el mismo o utilizando un GROUP BY tirando de la cláusula WHERE externa en la subconsulta, pero lo necesito para la generación automática de SQL y no puedo usar ninguna de las alternativas por varias otras razones.

ACTUALIZACIÓN: Lo siento, la cuestión dio lugar a cierta confusión: La primera consulta es sólo un ejemplo de trabajo, para demostrar lo que No necesidad.

ACTUALIZACIÓN 2: Necesito ambas comparaciones u.id = p.user: Los primeros recuentos usuarios que se unieron antes de '2009-10-10', mientras que el otro es una condición de unión que asocia filas de la tabla correctamente.

+1

¿por qué la actualización 2? sql analizará la tabla derivada 'c' y obtendrá una lista completa de todos los ID de usuario y sus recuentos de publicaciones. el join 'ON c.user = u.id' solo devolverá usuarios que satisfagan la restricción joinDate en' u'. – oedo

+0

Oh, tienes toda la razón, parece que ese es mi error. Voy a marcar tu comandante como la respuesta aceptada :) – soulmerge

+0

gracias, me alegro de poder ayudar :) – oedo

Respuesta

14

Creo que eso no funcionará, porque está haciendo referencia a su tabla derivada 'c' como parte de una unión.

sin embargo, usted podría simplemente sacar el WHERE p.user = u.id y reemplazarlo con un GROUP BY p.user en la tabla derivada, porque el ON c.user = u.id tendrá el mismo efecto.

+0

Thx para la respuesta.Pero su consulta haría otra cosa: contaría a todos los usuarios independientemente de la fecha de incorporación. * editar *: lo siento, parece que olvidé el grupo interno por – soulmerge

0

muy cerca ...

WHERE t1.date = ( 
    SELECT MAX(date) 

cambio a

WHERE t1.date IN ( 
    SELECT MAX(date) 

Debido a que su consulta hace un MAX(), que siempre devolverá un solo día ... ya que su sub-SELECT tiene el filtro en la identificación única, debe darle lo que quiere.

+2

ese no es el problema que tiene OP, y también usar = en lugar de IN funcionará bien también. – oedo

+1

oedo's right - actualizó la pregunta para aclarar – soulmerge

14

¿No es esto lo que buscas?

SELECT u.username, c._postCount 
FROM User u 
INNER JOIN (
    SELECT p.user, COUNT(*) AS _postCount 
    FROM Posting p 
    GROUP BY p.user  
) c ON c.user = u.id 
WHERE u.joinDate < '2009-10-10'; 

La razón por la que esto funcionará es porque la naturaleza de la unión se filtrará en el usuario. No necesita tener una cláusula WHERE que se filtre explícitamente en el usuario.

+0

Ambas uniones son obligatorias y sirven para diferentes propósitos: actualicé la pregunta – soulmerge

+0

Creo que aún no entiendo. No necesita la cláusula where en el medio en absoluto, porque la unión entre c y u filtra a todos los usuarios sin publicaciones y correlaciona correctamente los registros en función del ID de usuario. Actualicé la publicación para reflejar lo que quiero decir. – Jeremy

+0

+1 Tienes razón, ese fue mi error (sin embargo, oedo fue más rápido) – soulmerge

-1

Esta solución es para postgresql. Puede usar LATERAL JOIN que está disponible en postgresql. Aquí es cómo puede usarlo en su consulta.

SELECT u.username, c._postCount 
FROM User u 
INNER JOIN LATERAL (
    SELECT p.user, COUNT(*) AS _postCount 
    FROM Posting p 
    WHERE p.user = u.id 
    GROUP BY p.user 
) c ON c.user = u.id 
WHERE u.joinDate < '2009-10-10'; 

Aquí hay una referencia que podría utilizar. https://medium.com/kkempin/postgresqls-lateral-join-bfd6bd0199df

Cuestiones relacionadas