PostgreSQL,按值分组

时间:2018-10-03 07:10:07

标签: postgresql

我遇到的情况是,我应该根据列值得出两组的求和结果。这是使用的表和查询的简短示例:

DROP TABLE IF EXISTS mytemptable;
CREATE TEMPORARY TABLE mytemptable(
    id          integer PRIMARY KEY,
    cat         text,
    val         decimal);

INSERT INTO mytemptable VALUES
               ( 1, ' ',  10),    
               ( 5, 'n',  4.2),
               ( 6, 'p', 15),
               ( 7, 'd', 10), --added
               ( 9, '',  10),
               (11, null, 2.3),
               (14, 'p',  4.16);

SELECT cat, SUM(val) FROM mytemptable
 GROUP BY cat
 ORDER BY cat;

...给出这样的结果:

"";10
" ";10
"d";10
"n";4.2
"p";19.16
"";2.3

从此代码中,我只需要求和两个组即可。一个来自cat ='p',另一个来自所有其他猫。
一遍就可以通过分组/拥有或类似方式获得类似的东西。例如GROUP BY cat ='p',cat IN('',''','n',null)。也许这里可能有两个以上的通缉条件。 如果是这样,请告诉我如何。

这种情况下的期望结果将是:

    "p";19.14 (summed val from cat 'p')
    "d";10    (summed val from cat 'd') --added
    " ";26.5  (summed val from other cat's than 'p' and 'd')

2 个答案:

答案 0 :(得分:2)

您可以使用CASE表达式进行分组,该表达式将所有p类别记录和所有其他非p记录一起存储:

SELECT
    CASE WHEN cat = 'p' THEN 'p' ELSE ' ' END AS cat,
    SUM(val)
FROM mytemptable
GROUP BY CASE WHEN cat = 'p' THEN 'p' ELSE ' ' END
ORDER BY cat DESC;

enter image description here

Demo

编辑:

如果您需要更多存储桶,则只需向CASE表达式添加更多级别,例如对于您更新的问题,请使用以下

CASE WHEN cat = 'p' THEN 'p'
     WHEN cat = 'd' THEN 'd'
     ELSE ' ' END

答案 1 :(得分:1)

demo: db<>fiddle

我会在子查询(或CTE)中“转换” cat值。然后,您只需要一个CASE子句。

SELECT
    cat,
    SUM(val)
FROM (
    SELECT
        val,
        CASE WHEN cat IN ('p') THEN cat ELSE ' ' END as cat
    FROM
        mytable
) s
GROUP BY
    cat

CTE版本:

WITH new_cat AS (
    SELECT
        val,
        CASE WHEN cat IN ('p') THEN cat ELSE ' ' END as cat
    FROM
        mytable
)
SELECT
    cat,
    SUM(val)
FROM 
    new_cat
GROUP BY
    cat

然后,您可以使用所需的每个值来扩展列表:

SELECT
    cat,
    SUM(val)
FROM (
    SELECT
        val,
        CASE WHEN cat IN ('p', 'd') THEN cat ELSE ' ' END as cat
    FROM
        mytable
) s
GROUP BY
    cat

结果:

cat   sum
d     10 
p     19.16
      22.3