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

PostgreSQL - Sub-Kueri Berkorelasi Gagal?

Beberapa poin penting tentang penggunaan SQL:

  • Anda tidak dapat menggunakan alias kolom dalam klausa WHERE, tetapi Anda dapat menggunakan klausa HAVING. Itulah penyebab kesalahan yang Anda dapatkan.
  • Anda dapat menghitung lebih baik menggunakan JOIN dan GROUP BY daripada menggunakan subkueri yang berkorelasi. Ini akan jauh lebih cepat.
  • Gunakan klausa HAVING untuk memfilter grup.

Inilah cara saya menulis kueri ini:

SELECT t1.id, COUNT(t2.id) AS num_things
FROM t1 JOIN t2 USING (id)
GROUP BY t1.id
HAVING num_things = 5;

Saya menyadari kueri ini dapat melewati JOIN dengan t1, seperti dalam solusi Charles Bretana. Tapi saya berasumsi Anda mungkin ingin kueri menyertakan beberapa kolom lain dari t1.

Re:pertanyaan di komentar:

Perbedaannya adalah WHERE klausa dievaluasi pada baris, sebelum GROUP BY mengurangi grup menjadi satu baris per grup. HAVING klausa dievaluasi setelah kelompok terbentuk. Jadi, Anda tidak dapat, misalnya, mengubah COUNT() grup dengan menggunakan HAVING; Anda hanya dapat mengecualikan grup itu sendiri.

SELECT t1.id, COUNT(t2.id) as num
FROM t1 JOIN t2 USING (id)
WHERE t2.attribute = <value>
GROUP BY t1.id
HAVING num > 5;

Dalam kueri di atas, WHERE filter untuk baris yang cocok dengan kondisi, dan HAVING filter untuk grup yang memiliki setidaknya lima hitungan.

Hal yang membuat kebanyakan orang kebingungan adalah ketika mereka tidak memiliki GROUP BY klausa, jadi sepertinya seperti HAVING dan WHERE dapat dipertukarkan.

WHERE dievaluasi sebelum ekspresi dalam daftar pilih. Ini mungkin tidak jelas karena sintaks SQL menempatkan daftar pilih terlebih dahulu. Jadi Anda dapat menghemat banyak komputasi mahal dengan menggunakan WHERE untuk membatasi baris.

SELECT <expensive expressions>
FROM t1
HAVING primaryKey = 1234;

Jika Anda menggunakan kueri seperti di atas, ekspresi dalam daftar pilih dihitung untuk setiap baris , hanya untuk membuang sebagian besar hasil karena HAVING kondisi. Namun, kueri di bawah menghitung ekspresi hanya untuk baris tunggal cocok dengan WHERE kondisi.

SELECT <expensive expressions>
FROM t1
WHERE primaryKey = 1234;

Jadi untuk rekap, kueri dijalankan oleh mesin basis data menurut serangkaian langkah:

  1. Buat kumpulan baris dari tabel, termasuk baris apa pun yang dihasilkan oleh JOIN .
  2. Evaluasi WHERE kondisi terhadap kumpulan baris, memfilter baris yang tidak cocok.
  3. Hitung ekspresi dalam daftar-pilih untuk setiap set baris.
  4. Terapkan alias kolom (perhatikan ini adalah langkah terpisah, yang berarti Anda tidak dapat menggunakan alias dalam ekspresi di daftar pilih).
  5. Singkat grup menjadi satu baris per grup, menurut GROUP BY klausa.
  6. Evaluasi HAVING ketentuan terhadap grup, menyaring grup yang tidak cocok.
  7. Urutkan hasil, menurut ORDER BY klausa.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana cara mengubah struktur data jsonb yang disimpan di Postgres

  2. PLINQ di ConcurrentQueue bukan multithreading

  3. Django berbeda tidak berfungsi

  4. Postgresql Stempel waktu saat ini pada Pembaruan

  5. Bagaimana cara menghapus semua spasi dari bidang dalam database Postgres dalam kueri pembaruan?