2010-01-12 1 views
25

Ich möchte in einer Abfrage einen Beitrag und den ersten Kommentar mit dem Beitrag verbunden bekommen. Hier ist, wie ich es in PostgreSQL mache:Oracle Unterabfrage sieht die Variable aus dem äußeren Block 2 Ebenen nicht

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 

und es funktioniert gut.

Allerdings bekomme ich in Oracle einen Fehler ORA-00904 p.post_id: ungültige Kennung.

Es scheint für einen Subselect zu funktionieren, aber ich kann den Kommentar mit nur einem nicht bekommen, weil ich rownum (kein Limit/Offset in Oracle) verwenden muss.

Was mache ich hier falsch?

+0

Wahrscheinlich verwenden Sie etwas 'LIMIT 1' auf' PostgreSQL': es unterstützt nicht 'rownum'. – Quassnoi

+0

ja, natürlich auf Postgres Limit – user248789

Antwort

44

Nein, Oracle korreliert die Unterabfragen nicht verschachtelt mehr als eine Ebene tief (und auch nicht MySQL).

Dies ist ein bekanntes Problem.

verwenden:

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

Dank Quassnoi, das ist natürlich eine gute Antwort (obwohl dumm komplex, aber wahrscheinlich verwog mich PostgreSQL ein bisschen). Entschuldigung dafür, dass ich nicht früher geantwortet habe, aber mein Arbeitgeber möchte nicht, dass ich StackOverflow benutze, der die Seite blockiert und Proxy benutzt Ich kann nur Fragen stellen, nicht kommentieren (wahrscheinlich ein Problem mit SO Ajax Code). – user248789

+2

Wenn Sie kreativ werden, können Sie dieses Problem umgehen, indem Sie die gefilterte Variable auf eine Ebene in der Unterabfrage ziehen. – chotchki

+1

+1, um auf das Problem von Oracle hinzuweisen und eine Problemumgehung anzuzeigen. PS: Ich mag Oracle, aber manchmal ist Postgres so viel einfacher zu benutzen. – Christian

3

Wenn Sie SQL benötigen, die plattformunabhängig ist, wird diese Arbeit:

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

Aber es setzt voraus, dass (post_id, created_date) der Primärschlüssel der Kommentare ist . Wenn dies nicht der Fall ist, erhalten Sie mehr als eine Zeile mit Kommentaren, die denselben created_date enthalten.

Auch ist es wahrscheinlich langsamer als die Lösung, die Analytik von Quassnoi verwendet.

+0

Das wäre ein bisschen gefährlich. Das Erstellungsdatum kann nicht garantiert werden. Aber nur die Verwendung von MIN (comment_id) sollte in Ordnung sein, da es aus der Sequenz stammt. Ich habe jedoch Quassnois Lösung benutzt. – user248789

Verwandte Themen