2010-01-12 7 views
25

Me gustaría obtener en una consulta una publicación y el primer comentario asociado con la publicación. Aquí es cómo lo hago en PostgreSQL:La subconsulta de Oracle no ve la variable desde el bloque externo 2 niveles hasta

SELECT p.post_id, 
(select * from 
(select comment_body from comments where post_id = p.post_id 
order by created_date asc) where rownum=1 
) the_first_comment 
FROM posts p 

y funciona bien.

Sin embargo, en Oracle recibo un error ORA-00904 p.post_id: identificador no válido.

Parece que funciona bien para una subselección, pero no puedo obtener el comentario con una sola porque tengo que usar rownum (sin límite/desplazamiento en Oracle).

¿Qué estoy haciendo mal aquí?

+0

Probablemente, utilice algo 'LIMIT 1' en' PostgreSQL': no admite 'rownum'. – Quassnoi

+0

sí, por supuesto en el límite usado de postgres – user248789

Respuesta

44

No, Oracle no correlaciona las subconsultas anidadas con más de un nivel de profundidad (y tampoco lo hace MySQL).

Este es un problema bien conocido.

Utilice esta:

SELECT p.post_id, c.* 
FROM posts 
JOIN (
     SELECT c.*, ROW_NUMBER() OVER (PARTITION BY post_id ORDER BY created_date ASC) AS rn 
     FROM comments c 
     ) c 
ON  c.post_id = p.post_id 
     AND rn = 1 
+1

Gracias Quassnoi, esa es por supuesto una buena respuesta (aunque estúpidamente compleja, pero probablemente PostgreSQL me echó un poco de menos). Perdón por no haber respondido antes, pero a mi empleador no le gusta que use StackOverflow bloqueando el sitio y al usar el proxy solo puedo hacer preguntas, no comentar (probablemente un problema con el código SO ajax). – user248789

+2

Si se vuelve creativo, puede evitar este problema al subir la variable filtrada un nivel en la subconsulta. – chotchki

+1

+1 para señalar el problema de Oracle y mostrar una solución alternativa. PD: Me gusta Oracle, pero a veces Postgres es mucho más fácil de usar. – Christian

3

Si necesita SQL que es independiente de la plataforma, esto va a funcionar:

SELECT p.post_id 
    , c.comment_body 
    FROM posts p 
    , comments c 
WHERE p.post_id = c.post_id 
    AND c.created_date IN 
     (SELECT MIN(c2.created_date) 
      FROM comments c2 
      WHERE c2.post_id = p.post_id 
     ); 

Pero asume que (post_id, created_date) es la clave principal de los comentarios . Si no es así, obtendrá más de una línea de publicaciones que tengan comentarios con la misma fecha_crecida.

Además, es probable que sea más lento que la solución que utiliza análisis, proporcionada por Quassnoi.

+0

Eso sería un poco peligroso. No se puede garantizar que la fecha de creación sea única. Pero solo usar MIN (comment_id) debería estar bien ya que se toma de la secuencia. Aunque utilicé la solución de Quassnoi. – user248789

Cuestiones relacionadas