sql >> Database >  >> RDS >> PostgreSQL

FOUT:subquery in FROM kan niet verwijzen naar andere relaties van hetzelfde queryniveau

Bijwerken:

LATERAL joins maken dat mogelijk en werden geïntroduceerd met Postgres 9.3. Details:

De reden staat in de foutmelding. Een element van de FROM lijst kan niet verwijzen naar een ander element van de FROM lijst op hetzelfde niveau. Het is niet zichtbaar voor een peer op hetzelfde niveau. Je zou dit kunnen oplossen met een gecorreleerde subquery :

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

Het maakt je natuurlijk niet uit welke rij van RP jij kiest uit een reeks even dichte rijen, dus ik doe hetzelfde.

Echter, een subquery-expressie in de SELECT lijst kan slechts één retourneren kolom. Als u meer dan één of alle kolommen uit de tabel RP . wilt , gebruik zoiets als deze subqueryconstructie:
Ik neem aan dat er een primaire sleutel id bestaat in beide tabellen.

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

Gecorreleerde subquery's zijn berucht vanwege slechte prestaties . Dit soort zoekopdrachten - terwijl je natuurlijk berekent wat je wilt - zal zuigen in het bijzonder omdat de uitdrukking rp.t - rq.t kan geen index gebruiken. De prestaties zullen drastisch verslechteren met grotere tafels.

Deze herschreven query zou een index op RP.t moeten kunnen gebruiken , die veel zou moeten presteren sneller met grote tafels .

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;

Nogmaals, als je de hele rij wilt:

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;

Let op het gebruik van haakjes bij samengestelde typen ! Geen enkele ouder is hier overbodig. Meer daarover in de handleiding hier en hier .

Getest met PostgreSQL 9.1. Demo op sqlfiddle.



  1. kan geen verbinding maken met mysql op AWS RDS (fout 2003)

  2. MySQL 5.7:converteer eenvoudige JSON_ARRAY naar rijen

  3. Oracle MERGE verhoogt ORA-00904 fout

  4. planningstaak maken zonder Cron-taak