PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

GALAT:subquery di FROM tidak dapat merujuk ke relasi lain dengan level kueri yang sama

Pembaruan:

LATERAL bergabung memungkinkan itu dan diperkenalkan dengan Postgres 9.3. Detail:

Alasannya ada di pesan kesalahan. Salah satu elemen FROM list tidak dapat merujuk ke elemen lain dari FROM daftar pada tingkat yang sama. Itu tidak terlihat untuk rekan di level yang sama. Anda bisa menyelesaikan ini dengan subkueri berkorelasi :

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

Jelas, Anda tidak peduli baris mana dari RP Anda memilih dari sekumpulan baris yang sama dekat, jadi saya melakukan hal yang sama.

Namun, ekspresi subquery di SELECT list hanya dapat mengembalikan satu kolom. Jika Anda ingin lebih dari satu atau semua kolom dari tabel RP , gunakan sesuatu seperti konstruksi subquery ini:
Saya menganggap keberadaan kunci utama id di kedua tabel.

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

Subkueri terkait terkenal karena kinerja buruk . Kueri semacam ini - meskipun dengan jelas menghitung apa yang Anda inginkan - akan menyebalkan khususnya, karena ekspresi rp.t - rq.t tidak dapat menggunakan indeks. Performa akan menurun secara drastis dengan tabel yang lebih besar.

Kueri yang ditulis ulang ini harus dapat menggunakan indeks pada RP.t , yang seharusnya berkinerja banyak lebih cepat dengan tabel besar .

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;

Sekali lagi, jika Anda menginginkan seluruh baris:

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;

Perhatikan penggunaan kurung dengan tipe komposit ! Tidak ada paren yang berlebihan di sini. Selengkapnya tentang itu di manual di sini dan di sini .

Diuji dengan PostgreSQL 9.1. Demo di 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. Pemantauan Dinamis Instance PostgreSQL Menggunakan pg_top

  2. Basis data postgres restful Api express

  3. Bagaimana cara mengelola koneksi db di server?

  4. Instal RPostgreSQL pada RHEL 6.5 libpq-fe.h Error

  5. Kondisi sequence pada join table tidak bekerja dengan kondisi limit