您可以考虑将数据分组并使用STRING_AGG,如下所示
转化 1
下面的代码按Level1 和Level2 分组,并在重命名为LEVEL3 之前对Level3 求和
SELECT
Level1,
Level2,
SUM(Level3) as Level3
FROM
my_table
GROUP BY
Level1,
Level2;
| Level1 |
Level2 |
Level3 |
| US |
CA |
37000 |
| FR |
PA |
30888 |
| US |
LA |
10000 |
| UK |
LN |
1100 |
| FR |
DF |
1000 |
转化 2
下面的查询使用上一个查询的结果作为子查询(如果需要,也可以用作 CTE)并使用STRING_AGG 函数连接基于LEVEL1 的分组结果。如果需要,您可以另外订购结果。
SELECT
Level1,
STRING_AGG(Level2,',') as Level2,
STRING_AGG(Level3,',') as Level3
FROM (
SELECT
Level1,
Level2,
SUM(Level3) as Level3
FROM
my_table
GROUP BY
Level1,
Level2
) t
GROUP BY
Level1
| Level1 |
Level2 |
Level3 |
| FR |
PA,DF |
30888,1000 |
| UK |
LN |
1100 |
| US |
CA,LA |
37000,10000 |
Working example on db-fiddle here
编辑 1:
对于不支持 STRING_AGG 的 SQL Server 版本,可以使用以下方法使用 JOIN 和 CROSS APPLY 与 FOR XML PATH 来连接列:
WITH group_1 as (
SELECT
Level1,
Level2,
CONVERT(VARCHAR(10),SUM(Level3)) as Level3
FROM
my_table
GROUP BY
Level1,
Level2
),
level2_grouped AS (
SELECT
Level1,
LEFT(MergedValues,LEN(MergedValues)-1) AS Level2
FROM group_1 extern
CROSS APPLY (
SELECT
Level2+','
FROM
group_1 intern
WHERE
extern.Level1 = intern.Level1
FOR XML PATH('')
)merged(MergedValues)
),
level3_grouped AS (
SELECT
Level1,
LEFT(MergedValues,LEN(MergedValues)-1) AS Level3
FROM group_1 extern
CROSS APPLY (
SELECT
Level3+','
FROM
group_1 intern
WHERE
extern.Level1 = intern.Level1
FOR XML PATH('')
)merged(MergedValues)
)
SELECT
g1.Level1,
l2.Level2,
l3.Level3
FROM
group_1 g1
INNER JOIN
level2_grouped l2 ON g1.Level1 = l2.Level1
INNER JOIN
level3_grouped l3 ON g1.Level1 = l3.Level1
GROUP BY
g1.Level1,
l2.Level2,
l3.Level3
或者更简单
WITH group_1 as (
SELECT
Level1,
Level2,
CONVERT(VARCHAR(10),SUM(Level3)) as Level3
FROM
my_table
GROUP BY
Level1,
Level2
),
level_grouped AS (
SELECT
Level1,
LEFT(Merged2Values,LEN(Merged2Values)-1) AS Level2,
LEFT(Merged3Values,LEN(Merged3Values)-1) AS Level3
FROM group_1 extern
CROSS APPLY (
SELECT
Level2+','
FROM
group_1 intern
WHERE
extern.Level1 = intern.Level1
FOR XML PATH('')
)merged2(Merged2Values)
CROSS APPLY (
SELECT
Level3+','
FROM
group_1 intern
WHERE
extern.Level1 = intern.Level1
FOR XML PATH('')
)merged3(Merged3Values)
)
SELECT
Level1,
Level2,
Level3
FROM
level_grouped g1
GROUP BY
Level1,
Level2,
Level3
Working db fiddle
让我知道这是否适合你