FILTERCláusula agregada en Postgres 9.4+
Desde Postgres 9.4 hay una manera limpia y rápida (estándar 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;
totalse suma low, midy high, a no ser nulo o demás valores están involucrados.
Enlaces:
Lea también a continuación.
Postgres 9.3-
Hay un par de técnicas:
@Phil proporcionó la forma estándar con una CASEdeclaración (excepto sum(1), que no es la forma estándar). Me gusta usar una forma más corta:
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;
Si sus valores son como se definen en su pregunta (sólo 0- 10es posible), simplificar aún más:
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;
Un poco más corto, apenas más rápido.
Diferencias sutiles
Hay sutiles diferencias cuando se compara con sum()en la respuesta de Phil :
- Lo más importante, por documentación : - 
  - Cabe señalar que, a excepción de - count, estas funciones devuelven un valor nulo cuando no se seleccionan filas. En particular,- sumde ninguna fila devuelve nulo, no cero como cabría esperar ...
 
 
- count(*)es la forma estándar y un poco más rápido que- sum(1). De nuevo, se aplica nulo vs. 0.
 
Cualquiera de estas consultas (incluidas las de Phil) cuenta valores nulos para total. Si eso no es deseable, use en su lugar:
count(score) AS total_not_null
SQL Fiddle en la página 9.3. 
db <> violín aquí en la página 10.