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

PostgreSQL - pilih count(*) untuk baris di mana kondisi berlaku

Membangun sesuai aslinya

Kueri asli Anda berada di jalur yang benar untuk mengecualikan baris yang menyinggung. Anda baru saja memiliki > bukannya = . Langkah rumit untuk menghitung tidak ada.

SELECT count(*) AS ct
FROM  (
   SELECT 1
   FROM   compatibility c
   WHERE  rating_id = 1
   AND    NOT EXISTS (
      SELECT 1
      FROM   compatibility c2
      WHERE  c2.rating_id > 1
      AND   (c2.attr1_id = c.attr1_id AND c2.attr2_id = c.attr2_id OR
             c2.attr1_id = c.attr2_id AND c2.attr2_id = c.attr1_id))
   GROUP  BY least(attr1_id, attr2_id), greatest(attr1_id, attr2_id)
   ) sub;

Lebih pendek

Mungkin lebih cepat juga.

SELECT count(*) AS ct
FROM  (
   SELECT 1  -- selecting more columns for count only would be a waste
   FROM   compatibility
   GROUP  BY least(attr1_id, attr2_id), greatest(attr1_id, attr2_id)
   HAVING every(rating_id = 1)
   ) sub;

Mirip dengan kueri @Clodoaldo atau jawaban sebelumnya dengan penjelasan lebih lanjut .
every(rating_id = 1) lebih sederhana dari not bool_or(rating_id > 1) , tetapi juga mengecualikan rating < 1 - yang mungkin baik-baik saja (atau bahkan lebih baik) untuk kasus Anda.

MySQL saat ini tidak mengimplementasikan (SQL standar!) every() . Karena Anda hanya ingin menghilangkan rating_id > 1 , ekspresi sederhana ini lebih sesuai dengan kebutuhan Anda dan berfungsi di kedua RDBMS:

HAVING max(rating_id) = 1

Terpendek

Dengan count(*) sebagai fungsi agregat jendela dan tanpa subquery.

SELECT count(*) OVER () AS ct
FROM   compatibility
GROUP  BY least(attr1_id, attr2_id), greatest(attr1_id, attr2_id)
HAVING max(rating_id) = 1
LIMIT  1;

Fungsi jendela diterapkan setelah langkah agregat. Berdasarkan ini, kita mendapatkan dua langkah agregat yang dilakukan dalam satu tingkat kueri:

  1. Lipat setara (atr1_id, atr2_id) , tidak termasuk baris dengan rating_id yang berbeda ada.
  2. Hitung baris yang tersisa dengan fungsi jendela di seluruh rangkaian.

LIMIT 1 untuk mendapatkan satu baris (semua baris akan identik).
MySQL tidak memiliki fungsi jendela. Posgres saja.
Terpendek, belum tentu tercepat.

SQL Fiddle. (Pada hal9.2 karena hal9.3 sedang offline.)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Apa cara tercepat untuk melakukan penyisipan massal ke Postgres?

  2. Kueri spasial pada tabel besar dengan beberapa self join berkinerja lambat

  3. Hubungan Satu-ke-Banyak di (Postgre)SQL

  4. Pilih kolom dengan nama kolom tertentu di PostgreSQL

  5. PostgreSQL -harus muncul di klausa GROUP BY atau digunakan dalam fungsi agregat