FILTERMệnh đề tổng hợp trong Postgres 9.4+
Vì Postgres 9.4, có một cách nhanh chóng và nhanh chóng (tiêu chuẩn SQL):
SELECT count(*) FILTER (WHERE score BETWEEN 0 AND 3) AS low
, count(*) FILTER (WHERE score BETWEEN 4 AND 7) AS mid
, count(*) FILTER (WHERE score BETWEEN 8 AND 10) AS high
, count(*) AS total
FROM foo;
totalcộng lại low, midvà high, trừ khi NULL hoặc các giá trị khác có liên quan.
Liên kết:
Cũng đọc dưới đây.
Hậu 9,3-
Có một vài kỹ thuật:
@Phil cung cấp cách tiêu chuẩn với một CASEtuyên bố (ngoại trừ sum(1), đó không phải là cách tiêu chuẩn). Tôi thích sử dụng một hình thức ngắn hơn:
SELECT count(score BETWEEN 0 AND 3 OR NULL) AS low
, count(score BETWEEN 4 AND 6 OR NULL) AS mid
, count(score BETWEEN 7 AND 10 OR NULL) AS high
, count(*) AS total
FROM foo;
Nếu các giá trị của bạn như được xác định trong câu hỏi của bạn (chỉ 0- 10có thể), hãy đơn giản hóa hơn nữa:
SELECT count(score < 4 OR NULL) AS low
, count(score BETWEEN 4 AND 6 OR NULL) AS mid
, count(score > 6 OR NULL) AS high
, count(*) AS total
FROM foo;
Ngắn hơn một chút, nhanh hơn
Sự khác biệt tinh tế
Có khác biệt tinh tế khi so sánh với sum()trong câu trả lời của Phil :
Quan trọng nhất, mỗi tài liệu :
Cần lưu ý rằng ngoại trừ count, các hàm này trả về giá trị null khi không có hàng nào được chọn. Cụ thể, sumkhông có hàng nào trả về null, không phải bằng 0 như người ta mong đợi, ...
count(*) là cách tiêu chuẩn và nhanh hơn một chút sum(1). Một lần nữa, null so với 0 áp dụng.
Một trong hai truy vấn này (bao gồm cả Phil) đều tính các giá trị null cho total. Nếu đó là điều không mong muốn, hãy sử dụng thay thế:
count(score) AS total_not_null
Câu đố SQL trong trang 9.3.
db <> fiddle ở đây trong pg 10.