Postgresql

在單個 SELECT 語句中返回多個範圍的計數

  • March 15, 2021

我有一個 Postgres 數據庫表foo,其中有一列score範圍從 0 到 10。我想要一個查詢來返回總分數、0 到 3 之間的分數數、4 之間的分數數和 6,以及 7 到 10 之間的分數。類似於以下內容:

SELECT
 COUNT(*) as total,
 COUNT(
   SELECT * from foo where score between 0 and 3;
 ) as low,
 COUNT(
   SELECT * from foo where score between 4 and 6;
 ) as mid,
 COUNT(
   SELECT * from foo where score between 7 and 10;
 ) as high
FROM foo;

SELECT我試過這個,但在COUNT語句中出現錯誤。任何想法我怎麼能做到這一點?我確信在 Postgres 中有一個超級簡單的方法。我只是想不出Google的正確條款。

只需SUM()為每個數字範圍的每列使用條件語句。SUM(1)假設表中的所有數據都在某個範圍內,則只需使用 就可以對總數進行求和- 如果不是,則將其與其他數據一樣進行限制。

select sum(case when score between 0 and 3 then 1 else 0 end) as minrange,
      sum(case when score between 4 and 6 then 1 else 0 end) as midrange,
      sum(case when score between 7 and 10 then 1 else 0 end) as maxrange,
      sum(1) as total
from foo;

SQL小提琴連結

FILTERPostgres 9.4+ 中的聚合子句

從 Postgres 9.4 開始,有一種干淨快速(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加起來和low,除非涉及 NULL 或其他值。mid``high

連結:

另請閱讀下文。

Postgres 9.3-

有幾個技巧:

@Phil提供了一個帶有CASE語句的通用替代方法(除了sum(1),這不是標準方式)。我喜歡使用更短的形式:

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;

如果您的值與您的問題中定義的一樣(僅0-10可能),請進一步簡化:

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;

稍微短一點,快一點。

細微差別

與菲爾的回答相比,存在細微的差異sum()

需要注意的是,除了 之外count,這些函式在沒有選擇行時返回空值。特別是,sumof no rows 返回 null,而不是預期的零,…

  • count(*) 標準方式,比sum(1). 同樣,null vs. 0 適用。

這些查詢中的任何一個(包括 Phil 的)都將total. 如果這不是可取的,請改用:

count(score) AS total_not_null

db<>fiddle here

sqlfiddle (pg 9.3)

引用自:https://dba.stackexchange.com/questions/93510