PostgreSQL:如何获得值的总和以及进入每个值的总行数?

Mis*_*a M 2 postgresql aggregate

我有一张表格,MyData格式如下:

|id|theme_id|priority_id|value|
Run Code Online (Sandbox Code Playgroud)

我正在尝试为所有行获得以下结果:

theme_id | priority_id | total | sum
------------------------------------
    1    |      1      |   3   |  5
    1    |      2      |   5   |  12
    1    |      3      |   1   |  3
    2    |      1      |   2   |  6
Run Code Online (Sandbox Code Playgroud)

我们的想法是组中的所有行通过theme_idpriority_id再总结的数值为分组,以及,以获取进入那笔总行。

当我尝试以下操作时,我得到一个与 sum 列相等的 total 列:

|id|theme_id|priority_id|value|
Run Code Online (Sandbox Code Playgroud)

我也试过:

SELECT theme_id, priority_id, sum(value) AS values, count(id) as total
FROM MyData
GROUP BY theme_id, priority_id
Run Code Online (Sandbox Code Playgroud)

以上两个都给了我相同的输出:

theme_id | priority_id | total | sum
------------------------------------
    1    |      1      |   5   |  5
    1    |      2      |   12  |  12
    1    |      3      |   3   |  3
    2    |      1      |   6   |  6
Run Code Online (Sandbox Code Playgroud)

MDC*_*CCL 6

我创建了以下示例DDL结构以进行必要的查询:

CREATE TABLE my_data
(
    my_data_id  SERIAL,
    theme_id    INT NOT NULL,
    priority_id INT NOT NULL,  
    my_value    INT NOT NULL,
    CONSTRAINT pk_my_data PRIMARY KEY (my_data_id)  
);

CREATE TABLE theme
(
    theme_id  SERIAL,
    name      CHAR(6) NOT NULL,
    CONSTRAINT pk_theme PRIMARY KEY (theme_id)  
);

CREATE TABLE priority
(
    priority_id  SERIAL,
    name         CHAR(6) NOT NULL,
    CONSTRAINT pk_priority PRIMARY KEY (priority_id)  
);
Run Code Online (Sandbox Code Playgroud)

然后,将以下测试数据插入到相应的表中:

INSERT INTO theme (name)
VALUES ('first');
INSERT INTO theme (name)
VALUES ('second');
INSERT INTO theme (name)
VALUES ('third');

INSERT INTO priority (name)
VALUES ('high');
INSERT INTO priority (name)
VALUES ('medium');
INSERT INTO priority (name)
VALUES ('low');

INSERT INTO my_data (theme_id, priority_id, my_value)
VALUES (1, 1, 6);
INSERT INTO my_data (theme_id, priority_id, my_value)
VALUES (1, 2, 5);
INSERT INTO my_data (theme_id, priority_id, my_value)
VALUES (1, 3, 8);
INSERT INTO my_data (theme_id, priority_id, my_value)
VALUES (1, 1, 3);
INSERT INTO my_data (theme_id, priority_id, my_value)
VALUES (1, 2, 4);
INSERT INTO my_data (theme_id, priority_id, my_value)
VALUES (1, 3, 11);

INSERT INTO my_data (theme_id, priority_id, my_value)
VALUES (2, 1, 7);
INSERT INTO my_data (theme_id, priority_id, my_value)
VALUES (2, 2, 3);
INSERT INTO my_data (theme_id, priority_id, my_value)
VALUES (2, 3, 9);
INSERT INTO my_data (theme_id, priority_id, my_value)
VALUES (2, 1, 1);
INSERT INTO my_data (theme_id, priority_id, my_value)
VALUES (2, 2, 13);
INSERT INTO my_data (theme_id, priority_id, my_value)
VALUES (2, 3, 10);

INSERT INTO my_data (theme_id, priority_id, my_value)
VALUES (3, 1, 1);
INSERT INTO my_data (theme_id, priority_id, my_value)
VALUES (3, 2, 8);
INSERT INTO my_data (theme_id, priority_id, my_value)
VALUES (3, 3, 2);
INSERT INTO my_data (theme_id, priority_id, my_value)
VALUES (3, 1, 6);
INSERT INTO my_data (theme_id, priority_id, my_value)
VALUES (3, 2, 5);
INSERT INTO my_data (theme_id, priority_id, my_value)
VALUES (3, 3, 4);
Run Code Online (Sandbox Code Playgroud)

最后是具体的 SELECT 语句及其相应的聚合函数,可提供所需的结果集:

SELECT theme_id, 
       priority_id, 
       SUM(my_value) AS values_sum, 
       COUNT(*)      AS total_rows
  FROM my_data
GROUP BY theme_id, priority_id 
ORDER BY theme_id ASC, priority_id ASC;
Run Code Online (Sandbox Code Playgroud)

通过这种方式,我们可以看到您的第二个查询几乎已经有了它,但是正如@a_horse_with_no_name指出的那样,您需要替换count(id)count(*),以便您可以获得正确的数据。我还包含了用于对列进行排序的 ORDER BY 子句。

通过这个 SQL Fiddle 示例,您可以确认 SUM 和 COUNT 产生的结果是正确的。如您所见,我添加了themepriority,它们是此查询的相关表,以及所需的测试数据。