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

Catatan yang dikembalikan dari fungsi memiliki kolom yang digabungkan

Umumnya, untuk menguraikan baris dikembalikan dari suatu fungsi dan mendapatkan kolom individual:

SELECT * FROM account_servicetier_for_day(20424, '2014-08-12');

Adapun pertanyaannya:

Postgres 9.3 atau lebih baru

Pembersih dengan JOIN LATERAL :

SELECT '2014-08-12' AS day, 0 AS inbytes, 0 AS outbytes
     , a.username, a.accountid, a.userid
     , f.*   -- but avoid duplicate column names!
FROM   account_tab a
     , account_servicetier_for_day(a.accountid, '2014-08-12') f  -- <-- HERE
WHERE  a.isdsl = 1
AND    a.dslservicetypeid IS NOT NULL
AND    NOT EXISTS (
   SELECT 1
   FROM   dailyaccounting_tab
   WHERE  day = '2014-08-12'
   AND    accountid = a.accountid
   )
ORDER  BY a.username;

LATERAL kata kunci tersirat di sini, fungsi selalu dapat merujuk FROM sebelumnya item. Panduan:

LATERAL juga dapat mendahului panggilan fungsi FROM item, tetapi dalam hal ini adalah kata derau, karena ekspresi fungsi dapat merujuk ke FROM sebelumnya item dalam hal apa pun.

Terkait:

  • Menyisipkan beberapa baris dalam satu tabel berdasarkan nomor di tabel lain

Notasi pendek dengan koma di FROM list (kebanyakan) setara dengan CROSS JOIN LATERAL (sama seperti [INNER] JOIN LATERAL ... ON TRUE ) dan dengan demikian menghapus baris dari hasil di mana panggilan fungsi tidak mengembalikan baris. Untuk mempertahankan baris tersebut, gunakan LEFT JOIN LATERAL ... ON TRUE :

...
FROM  account_tab a
LEFT  JOIN LATERAL account_servicetier_for_day(a.accountid, '2014-08-12') f ON TRUE
...

Juga, jangan gunakan NOT IN (subquery) ketika Anda bisa menghindarinya. Ini adalah beberapa cara paling lambat dan paling rumit untuk melakukannya:

  • Pilih baris yang tidak ada di tabel lain

Saya sarankan NOT EXISTS sebagai gantinya.

Postgres 9.2 atau lebih lama

Anda dapat memanggil fungsi set-return di SELECT list (yang merupakan ekstensi Postgres dari SQL standar). Untuk alasan kinerja, ini paling baik dilakukan dalam subquery. Dekomposisi tipe baris (terkenal!) di kueri luar untuk menghindari evaluasi fungsi berulang:

SELECT '2014-08-12' AS day, 0 AS inbytes, 0 AS outbytes
     , a.username, a.accountid, a.userid
     , (a.rec).*   -- but avoid duplicate column names!
FROM  (
   SELECT *, account_servicetier_for_day(a.accountid, '2014-08-12') AS rec
   FROM   account_tab a
   WHERE  a.isdsl = 1
   AND    a.dslservicetypeid Is Not Null
   AND    NOT EXISTS (
       SELECT 1
       FROM   dailyaccounting_tab
       WHERE  day = '2014-08-12'
       AND    accountid = a.accountid
      )
   ) a
ORDER  BY a.username;

Jawaban terkait oleh Craig Ringer dengan penjelasan, mengapa kami lebih baik menguraikan di kueri luar:

  • Bagaimana cara menghindari beberapa evaluasi fungsi dengan sintaks (func()).* dalam kueri SQL?

Postgres 10 menghilangkan keanehan dalam perilaku fungsi pengembalian set di SELECT :

  • Apa perilaku yang diharapkan untuk beberapa fungsi pengembalian-set dalam klausa SELECT?


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tentukan nama tabel dan kolom sebagai argumen dalam fungsi plpgsql?

  2. Scaling PostgreSQL Menggunakan Connection Poolers &Load Balancers

  3. Panggilan fungsi PostgreSQL

  4. Bagaimana cara membuat ekstensi postgres di dalam wadah?

  5. Alat untuk menghasilkan diagram tabel database dengan PostgreSQL?