SQL 查询 GROUP BY 组
Posted
技术标签:
【中文标题】SQL 查询 GROUP BY 组【英文标题】:SQL query GROUP BY groups 【发布时间】:2022-01-03 08:55:02 【问题描述】:我有这样的事情:
id | name | totalAmount |
---|---|---|
1 | name1 | 10 |
2 | name1 | 20 |
3 | name1 | 25 |
4 | name2 | 5 |
5 | name2 | 12 |
并且需要看起来像这样:
id's | name | totalAmount |
---|---|---|
1,2 | name1 | 30 |
2,3 | name1 | 45 |
1,3 | name1 | 35 |
1,2,3 | name1 | 55 |
4,5 | name2 | 17 |
我正在使用STRING_AGG
,但不知道如何在前 3 个 id 中分隔。
【问题讨论】:
根据问题指南,请展示您的尝试并告诉我们您发现了什么(在本网站或其他地方)以及为什么它不能满足您的需求。 我在您的数据中看不到任何模式,或者看不到如何您的输出数据可以从您的源数据中导出。为什么有些值比其他值重复得更多?name
重要吗?为什么1
和2
组合在一起,而2
和3
而不是1
和3
?
@Dai,1和3必须合并,我的错。
@IvanC 这不会扩展:如果你有 3 个输入行(a
、b
、c
)那么你有 4 个输出行(a+b
、@987654335 @、a+c
和 a+b+c
);如果你有 4 个输入行(a
、b
、c
、d
)那么你有 9 个输出行(a+b
、a+c
、a+d
、b+c
、b+d
, c+d
,a+b+c
,b+c+d
,a+b+c+d
,对于 5 个输入行,输出继续爆炸......我怀疑你真的想这样做......
那么具体是什么逻辑,很不清楚
【参考方案1】:
这是一个递归版本,它可以处理超过 3 个名称的 id 并返回所有可能的组合。正如戴指出的那样,当组合的数量迅速增加时要小心。但是,如果您的真实数据与您的示例类似(通常每个名称 2-3 个 id),那应该没问题。
值得注意的是,我这样做是为了好玩。可能你最好只存储原始数据并在应用层做这种恶作剧。
CREATE TABLE #data
(
id INT,
[name] VARCHAR(10),
totalAmount INT
);
INSERT INTO #data
VALUES
(1, 'name1', 10),
(2, 'name1', 20),
(3, 'name1', 25),
(4, 'name2', 5),
(5, 'name2', 12);
WITH cte (name, ids, maxid, tot) AS
(
SELECT a.name,
CONVERT(VARCHAR(8000), CONVERT(VARCHAR(10), a.id) + ',' + CONVERT(VARCHAR(10), b.id) ) AS ids,
b.id AS maxid,
a.totalAmount + b.totalAmount AS tot
FROM #data a
INNER JOIN #data b ON b.name = a.name AND a.id < b.id
UNION ALL
SELECT cte.name,
CONVERT(VARCHAR(8000), cte.ids + ',' +CONVERT(VARCHAR(10), a.id)),
a.id AS maxid,
cte.tot + a.totalAmount
FROM cte
INNER JOIN #data a ON cte.name = a.name
WHERE a.id > cte.maxid
)
SELECT ids, name, tot
FROM cte
【讨论】:
【参考方案2】:-- *** Test Data ***
CREATE TABLE #t
(
id int NOT NULL PRIMARY KEY
,[name] nvarchar(30) NOT NULL
,totalAmount money NOT NULL
);
INSERT INTO #t
VALUES (1, 'name1', 10)
,(2, 'name1', 20)
,(3, 'name1', 25)
,(4, 'name2', 5)
,(5, 'name2', 12);
-- *** End Test Data ***
SELECT CAST(T1.id AS varchar(10))
+ ',' + CAST(T2.id AS varchar(10)) AS ids
,T1.[name] AS [name]
,T1.totalAmount + T2.totalAmount AS totalAmount
FROM #t T1
JOIN #t T2
ON T1.[name] = T2.[name]
WHERE T1.id < T2.id
UNION ALL
SELECT CAST(T1.id AS varchar(10))
+ ',' + CAST(T2.id AS varchar(10))
+ ',' + CAST(T3.id AS varchar(10)) AS ids
,T1.[name] AS [name]
,T1.totalAmount + T2.totalAmount + T3.totalAmount AS totalAmount
FROM #t T1
JOIN #t T2
ON T1.[name] = T2.[name]
JOIN #t T3
ON T1.[name] = T3.[name]
WHERE T1.id < T2.id
AND T2.id < T3.id;
【讨论】:
以上是关于SQL 查询 GROUP BY 组的主要内容,如果未能解决你的问题,请参考以下文章
GROUP BY不适用于MySQL 5.7,因为5.7使用SQL_MODE的“ONLY_FULL_GROUP_BY”选项。
SQL中的Group By的查询过程多列分组的查询过程是怎样的?