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

Fungsi agregat pada beberapa tabel yang digabungkan

SELECT f.id, f.name, b.fb_ct, t.tag_names
FROM   foo f
LEFT JOIN  (
    SELECT foo_id AS id, count(*) AS fb_ct
    FROM   foo_bar
    GROUP  BY 1
    ) b USING (id)
LEFT JOIN  (
    SELECT target_id AS id, array_agg(name) AS tag_names
    FROM   tag
    GROUP  BY 1
    ) t USING (id)
ORDER  BY f.id;

Menghasilkan hasil yang diinginkan.

  • Tulis ulang dengan eksplisit JOIN sintaksis. Membuatnya lebih mudah untuk dibaca dan dipahami (dan di-debug).

  • Dengan bergabung ke beberapa 1:n tabel terkait, baris akan saling mengalikan menghasilkan produk Cartesian - yang sangat mahal omong kosong. Ini adalah CROSS JOIN yang tidak disengaja oleh proxy. Terkait:

  • Untuk menghindari ini, bergabunglah paling banyak satu n -tabel ke 1 -tabel sebelum Anda mengagregasi (GROUP BY ). Anda dapat mengagregasi dua kali, tetapi lebih bersih dan lebih cepat untuk mengagregasi n -tabel secara terpisah sebelum menggabungkan mereka ke 1 -meja.

  • Berbeda dengan aslinya (dengan INNER JOIN implisit) ). Saya menggunakan LEFT JOIN untuk menghindari kehilangan baris dari foo yang tidak memiliki baris yang cocok di foo_bar atau tag .

  • Setelah CROSS JOIN yang tidak diinginkan dihapus dari kueri, tidak perlu menambahkan DISTINCT lagi - dengan asumsi bahwa foo.id unik.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tidak ada Ruang Buffer yang tersedia (koneksi maksimum tercapai?) Formulir Postgres EDB Driver

  2. Django OperationalError:tidak dapat memotong proses baru untuk koneksi

  3. Metode yang tidak ditentukan auto_upgrade! saat mendorong aplikasi Sinatra/DataMapper ke Heroku

  4. Mengurutkan nilai kolom yang berbeda dengan (nilai pertama) kolom lain dalam fungsi agregat

  5. Postgres Periksa apakah IP (inet) DALAM daftar Rentang IP