PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

PostgreSQL - chọn số lượng (*) cho các hàng có điều kiện giữ

Xây dựng trên bản gốc của bạn

Truy vấn ban đầu của bạn đã đi đúng hướng để loại trừ các hàng vi phạm. Bạn vừa có > thay vì = . Đã thiếu bước khó đếm.

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;

Ngắn hơn

Có lẽ cũng nhanh hơn.

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;

Tương tự với truy vấn của @ Clodoaldo hoặc câu trả lời trước đó kèm theo giải thích rõ hơn .
every(rating_id = 1) đơn giản hơn not bool_or(rating_id > 1) , nhưng cũng loại trừ rating < 1 - điều này có thể tốt (hoặc thậm chí tốt hơn) cho trường hợp của bạn.

MySQL hiện không triển khai (SQL chuẩn!) every() . Vì bạn chỉ muốn loại bỏ rating_id > 1 , biểu thức đơn giản này phù hợp hơn với yêu cầu của bạn và hoạt động trong cả RDBMS:

HAVING max(rating_id) = 1

Ngắn nhất

Với count(*) dưới dạng hàm tổng hợp cửa sổ và không có truy vấn con.

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;

Các chức năng của cửa sổ được áp dụng sau bước tổng hợp. Dựa trên điều này, chúng tôi nhận được hai tổng hợp các bước được thực hiện trong một cấp truy vấn:

  1. Gấp tương đương (atr1_id, atr2_id) , loại trừ các hàng có rating_id khác nhau tồn tại.
  2. Đếm các hàng còn lại bằng chức năng cửa sổ trên toàn bộ tập hợp.

LIMIT 1 để có được một hàng duy nhất (tất cả các hàng sẽ giống nhau).
MySQL không có các chức năng cửa sổ. Postgres chỉ.
Ngắn nhất, không nhất thiết phải nhanh nhất.

SQL Fiddle. (Trên pg9.2 vì pg9.3 hiện đang ngoại tuyến.)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Postgresql ltree truy vấn để tìm cha mẹ có hầu hết con cái; loại trừ gốc

  2. Lược đồ PostgreSQL / Không gian tên với Django

  3. Triển khai thiết lập đa trung tâm dữ liệu cho PostgreSQL - Phần thứ hai

  4. Mối quan hệ lỗi không tồn tại

  5. Cách statement_timestamp () hoạt động trong PostgreSQL