转换 table 数据并重新格式化
Convert table data and reformat
我有 table 名为 Table
id
Level1
Level2
Level3
1
US
CA
13000
2
FR
PA
30000
3
US
CA
24000
4
US
LA
10000
5
UK
LN
500
6
UK
LN
600
7
FR
PA
888
8
FR
DF
1000
我想将其转换为下面的(第一次转换)格式,它将 Level2
和列组按 Level1 相加,如下所示
select Level1, level2, sum(level3) as level3
from table
group by level2
order by level1
然后(第二次转换)将具有相同 Level1
的公共行组合成如下所示
您可以考虑对数据进行分组并使用 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 服务器版本,可以使用以下使用 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
让我知道这是否适合你
我有 table 名为 Table
id | Level1 | Level2 | Level3 |
---|---|---|---|
1 | US | CA | 13000 |
2 | FR | PA | 30000 |
3 | US | CA | 24000 |
4 | US | LA | 10000 |
5 | UK | LN | 500 |
6 | UK | LN | 600 |
7 | FR | PA | 888 |
8 | FR | DF | 1000 |
我想将其转换为下面的(第一次转换)格式,它将 Level2
和列组按 Level1 相加,如下所示
select Level1, level2, sum(level3) as level3
from table
group by level2
order by level1
然后(第二次转换)将具有相同 Level1
的公共行组合成如下所示
您可以考虑对数据进行分组并使用 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 服务器版本,可以使用以下使用 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
让我知道这是否适合你