sql >> Databasteknik >  >> RDS >> PostgreSQL

FEL:underfrågan i FROM kan inte referera till andra relationer på samma frågenivå

Uppdatering:

LATERAL joins tillåter det och introducerades med Postgres 9.3. Detaljer:

Orsaken finns i felmeddelandet. Ett element i FROM Listan kan inte referera till ett annat element i FROM lista på samma nivå. Det är inte synligt för en peer på samma nivå. Du kan lösa detta med en korrelerad underfråga :

SELECT *, (SELECT t FROM rp ORDER BY abs(rp.t - rq.t) LIMIT 1) AS ra
FROM   rq

Du bryr dig självklart inte vilken rad från RP du väljer från en uppsättning lika nära rader, så jag gör detsamma.

Däremot ett underfrågeuttryck i SELECT listan kan bara returnera en kolumn. Om du vill ha mer än en eller alla kolumner från tabellen RP , använd något i stil med denna subquery-konstruktion:
Jag antar att det finns en primärnyckel id i båda tabellerna.

SELECT id, t, (ra).*
FROM (
    SELECT *, (SELECT rp FROM rp ORDER BY abs(rp.t - rq.t) LIMIT 1) AS ra
    FROM   rq
    ) x;

Korrelerade underfrågor är ökända för dålig prestanda . Den här typen av fråga - samtidigt som du uppenbarligen beräknar vad du vill - kommer att suga i synnerhet eftersom uttrycket rp.t - rq.t kan inte använda ett index. Prestanda kommer att försämras drastiskt med större bord.

Denna omskrivna fråga bör kunna använda ett index på RP.t , som borde prestera mycket snabbare med stora bord .

WITH x AS (
    SELECT * 
         ,(SELECT t
           FROM   rp
           WHERE  rp.t <  rq.t
           ORDER  BY rp.t DESC
           LIMIT  1) AS t_pre

         ,(SELECT t
           FROM   rp
           WHERE  rp.t >= rq.t
           ORDER  BY rp.t
           LIMIT  1) AS t_post
    FROM   rq
    )
SELECT id, t
      ,CASE WHEN (t_post - t) < (t - t_pre)
            THEN t_post
            ELSE COALESCE(t_pre, t_post) END AS ra
FROM   x;

Återigen, om du vill ha hela raden:

WITH x AS (
    SELECT * 
         ,(SELECT rp
           FROM   rp
           WHERE  rp.t <  rq.t
           ORDER  BY rp.t DESC
           LIMIT  1) AS t_pre

         ,(SELECT rp
           FROM   rp
           WHERE  rp.t >= rq.t
           ORDER  BY rp.t
           LIMIT  1) AS t_post
    FROM   rq
    ), y AS (
    SELECT id, t
          ,CASE WHEN ((t_post).t - t) < (t - (t_pre).t)
                THEN t_post
                ELSE COALESCE(t_pre, t_post) END AS ra
    FROM   x
    )
SELECT id AS rq_id, t AS rq_t, (ra).*
FROM   y 
ORDER  BY 2;

Observera användningen av parenteser med sammansatta typer ! Ingen förälder är överflödig här. Mer om det i manualen här och här .

Testad med PostgreSQL 9.1. Demo på sqlfiddle.



  1. Summa flera rader datumskillnad Mysql

  2. Utföra val och flera infogar som transaktion med C Connector?

  3. I klausul kontra OR-klausul prestationsmässigt

  4. Hur man hittar relation från Snomed Postgres SQL-databas