FILTER
Mệ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;
total
cộng lại low
, mid
và 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 CASE
tuyê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
- 10
có 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ể, sum
khô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.