PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

ГРЕШКА:подзаявка в FROM не може да препраща към други отношения от същото ниво на заявка

Актуализация:

LATERAL присъединяванията позволяват това и бяха въведени с Postgres 9.3. Подробности:

Причината е в съобщението за грешка. Един елемент от FROM списъкът не може да препраща към друг елемент от FROM списък на същото ниво. Не се вижда от партньор на същото ниво. Можете да разрешите това с корелирана подзаявка :

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

Очевидно не ви интересува кой ред от RP вие избирате от набор от еднакво близки редове, така че аз правя същото.

Обаче израз на подзаявка в SELECT списъкът може да върне само един колона. Ако искате повече от една или всички колони от таблицата RP , използвайте нещо като тази конструкция на подзаявка:
Предполагам съществуването на първичен ключ id и в двете таблици.

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

Корелираните подзаявки са известни с лошото представяне . Този вид заявка - въпреки че очевидно изчислява това, което искате - ще смущава по-специално, защото изразът rp.t - rq.t не може да използва индекс. Производителността ще се влоши драстично с по-големи маси.

Тази пренаписана заявка трябва да може да използва индекс на RP.t , което трябва да изпълнявамного по-бързо с големи масици .

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;

Отново, ако искате целия ред:

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;

Обърнете внимание на използването на скоби със съставни типове ! Нито един родител не е излишен тук. Повече за това в ръководството тук и тук .

Тестван с PostgreSQL 9.1. Демо на sqlfiddle.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Проверете дали таблицата на sqlachemy е празна

  2. Заредете PostgreSQL таблица от CSV с данни със запетаи между скоби

  3. Rails разширяващи полета с обхват, PG не го харесва

  4. Как да вмъкна стойност в оператор select с помощта на JavaScript, по-специално когато използвам express и postgres?

  5. Мета команди в Psycopg2 - \d не работят