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】:您可以创建一个子查询,获取每个人的 item
和 cost
的不同值,然后对其进行聚合:
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 基于其他列中的不同值(如果其他列中的值重复,则求和一次)的主要内容,如果未能解决你的问题,请参考以下文章
具有日期范围条件的 Group By 和 SUM 的 sql
HSQLDB:原因:使用 MAX,但不使用 Group By,并获取 java.sql.SQLSyntaxErrorException:表达式不在聚合或 GROUP BY 列中: