SQL group by 和 sum 基于其他列中的不同值(如果其他列中的值重复,则求和一次)

Posted

技术标签:

【中文标题】SQL group by 和 sum 基于其他列中的不同值(如果其他列中的值重复,则求和一次)【英文标题】:SQL group by and sum based on distinct value in other column (sum once if value in other column is duplicated) 【发布时间】:2020-12-30 12:12:30 【问题描述】:

我需要有关分组查询的帮助。我的桌子是这样的:

CREATE MULTISET TABLE MY_TABLE (PERSON CHAR(1), ITEM CHAR(1), COST INT);
INSERT INTO MY_TABLE VALUES ('A', '1', 5);
INSERT INTO MY_TABLE VALUES ('A', '1', 5);
INSERT INTO MY_TABLE VALUES ('A', '2', 1);
INSERT INTO MY_TABLE VALUES ('B', '3', 0);
INSERT INTO MY_TABLE VALUES ('B', '4', 10);
INSERT INTO MY_TABLE VALUES ('B', '4', 10);
INSERT INTO MY_TABLE VALUES ('C', '5', 1);
INSERT INTO MY_TABLE VALUES ('C', '5', 1);
INSERT INTO MY_TABLE VALUES ('C', '5', 1);
+--------+------+------+
| PERSON | ITEM | COST |
+--------+------+------+
| A      | 1    |    5 |
| A      | 1    |    5 |
| A      | 2    |    1 |
| B      | 3    |    0 |
| B      | 4    |   10 |
| B      | 4    |   10 |
| C      | 5    |    1 |
| C      | 5    |    1 |
| C      | 5    |    1 |
+--------+------+------+

我需要按人对项目和成本进行分组,但方式不同。对于每个人,我需要他们拥有的独特物品的数量。例如:A 的人有两个不同的项目,项目 1 和项目 2。我可以通过 COUNT(DISTINCT ITEM) 得到这个。

然后对于每个人,我需要对成本求和,但每个不同的项目只需要一次(对于重复的项目,成本始终相同)。例如:人 A 有 5 美元的项目 1、5 美元的项目 1 和 1 美元的项目 2。由于这个人有两次物品 1,我算了一次 5 美元,然后将物品 2 中的 1 美元相加,总共 6 美元。输出应如下所示:

+--------+---------------------+------------------------+
| PERSON | ITEM_DISTINCT_COUNT | COST_DISTINCT_ITEM_SUM |
+--------+---------------------+------------------------+
| A      |                   2 |                      6 |
| B      |                   2 |                     10 |
| C      |                   1 |                      1 |
+--------+---------------------+------------------------+

有没有一种简单的方法可以在很多行上表现良好?

SELECT PERSON
  ,COUNT(DISTINCT ITEM) ITEM_DISTINCT_COUNT
  -- help with COST_DISTINCT_ITEM_SUM
FROM MY_TABLE
GROUP BY PERSON

【问题讨论】:

您的目标系统真的是 Teradata 吗? TD 不支持这种多值语法。 @dnoeth 它是 Teradata。我更新了那段代码,谢谢。 【参考方案1】:

您可以创建一个子查询,获取每个人的 itemcost 的不同值,然后对其进行聚合:

SELECT PERSON, 
       COUNT(ITEM) AS ITEM_DISTINCT_COUNT,
       SUM(COST) AS COST_DISTINCT_ITEM_SUM 
FROM (
  SELECT DISTINCT PERSON, ITEM, COST
  FROM MY_TABLE
) M
GROUP BY PERSON

输出:

PERSON  ITEM_DISTINCT_COUNT     COST_DISTINCT_ITEM_SUM
A       2                       6
B       2                       10
C       1                       1

Demo on dbfiddle

【讨论】:

【参考方案2】:

我推荐两个级别的聚合:

select person, count(*) as num_items, sum(cost)
from (select person, item, avg(cost) as cost
      from my_table t
      group by person, item
     ) t
group by person;

【讨论】:

Gordon,有没有一种简单的方法可以在不编写 sql 查询的情况下为此类帖子创建表?我想要一个类似电子表格的工具,它可以让您输入数据并将其转换为 SQL 以创建表格。这样我就可以少打字了。 @ErranMorad 。 . .您拥有的插入语句对其他人最有用 - 好吧,实际的 SQL 或 DB Fiddle 会更有用。 @ErranMorad SQLFiddle 和 db-fiddle 都有文本到 DDL 工具,可以做你想做的事。

以上是关于SQL group by 和 sum 基于其他列中的不同值(如果其他列中的值重复,则求和一次)的主要内容,如果未能解决你的问题,请参考以下文章

关于SQL中两张表联合sum和group by的查询问题

SQL SUM 和 GROUP BY

SQL 3加入group by和sum函数[重复]

具有日期范围条件的 Group By 和 SUM 的 sql

HSQLDB:原因:使用 MAX,但不使用 Group By,并获取 java.sql.SQLSyntaxErrorException:表达式不在聚合或 GROUP BY 列中:

怎么使用group by?