如何旋转和合并以避免 NULL 单元格?
How to pivot and merge to avoid the NULL cells?
示例 table 数据:
SELECT [id],[date],[agent],[sales]
FROM [AgentSales]
id date agent sales
1 2021-01-02 00:00:00.000 Agent A 10
2 2021-01-03 00:00:00.000 Agent A 2
3 2021-01-04 00:00:00.000 Agent B 22
4 2021-01-06 00:00:00.000 Agent B 5
5 2021-02-05 00:00:00.000 Agent A 1
6 2021-02-06 00:00:00.000 Agent B 33
7 2021-03-06 00:00:00.000 Agent A 11
8 2021-03-06 00:00:00.000 Agent B 3
按年月分组,代理商:
SELECT CAST(YEAR([DATE]) AS VARCHAR)+' '+CAST(MONTH([DATE]) AS VARCHAR) YRMON, AGENT, SUM(SALES) SALES
FROM AgentSales
GROUP BY CAST(YEAR([DATE]) AS VARCHAR)+' '+CAST(MONTH([DATE]) AS VARCHAR), AGENT
ORDER BY 1
YRMON AGENT SALES
2021 1 Agent A 12
2021 1 Agent B 27
2021 2 Agent A 1
2021 2 Agent B 33
2021 3 Agent A 11
2021 3 Agent B 3
枢轴:
SELECT CAST(YEAR([DATE]) AS VARCHAR)+' '+CAST(MONTH([DATE]) AS VARCHAR) YRMON, [AGENT A], [AGENT B]
FROM AgentSales
PIVOT (SUM(SALES) FOR AGENT IN ([AGENT A], [AGENT B])) AS PIVOTTABLE
YRMON AGENT A AGENT B
2021 1 10 NULL
2021 1 2 NULL
2021 1 NULL 22
2021 1 NULL 5
2021 2 1 NULL
2021 2 NULL 33
2021 3 11 NULL
2021 3 NULL 3
我想用实际值代替 NULL。因此实际上每个 YearMon 应该只有 2 行。如何做到这一点?
预期结果:
YRMON AGENT A AGENT B
2021 1 12 27
2021 2 1 33
2021 3 11 3
看起来简单的条件聚合应该可以解决问题。
SELECT
FORMAT(EOMONTH([DATE]), 'yyyy MM') YRMON,
SUM(CASE WHEN AGENT = 'AGENT B' THEN SALES END) [AGENT B],
SUM(CASE WHEN AGENT = 'AGENT A' THEN SALES END) [AGENT A]
FROM AgentSales
GROUP BY EOMONTH([DATE])
ORDER BY EOMONTH([DATE]);
或者,如果您希望每一个都在单独的一行中,您可以添加一个行号并在其上分组
SELECT
FORMAT(EOMONTH([DATE]), 'yyyy MM') YRMON,
SUM(CASE WHEN AGENT = 'AGENT B' THEN SALES END) [AGENT B],
SUM(CASE WHEN AGENT = 'AGENT A' THEN SALES END) [AGENT A]
FROM (
SELECT *,
rn = ROW_NUMBER() OVER (PARTITION BY EOMONTH([DATE]), AGENT ORDER BY [DATE])
FROM AgentSales
) sales
GROUP BY EOMONTH([DATE]), rn
ORDER BY EOMONTH([DATE]), rn;
Grouping by EOMONTH
is more performant than grouping by a string
示例 table 数据:
SELECT [id],[date],[agent],[sales]
FROM [AgentSales]
id date agent sales
1 2021-01-02 00:00:00.000 Agent A 10
2 2021-01-03 00:00:00.000 Agent A 2
3 2021-01-04 00:00:00.000 Agent B 22
4 2021-01-06 00:00:00.000 Agent B 5
5 2021-02-05 00:00:00.000 Agent A 1
6 2021-02-06 00:00:00.000 Agent B 33
7 2021-03-06 00:00:00.000 Agent A 11
8 2021-03-06 00:00:00.000 Agent B 3
按年月分组,代理商:
SELECT CAST(YEAR([DATE]) AS VARCHAR)+' '+CAST(MONTH([DATE]) AS VARCHAR) YRMON, AGENT, SUM(SALES) SALES
FROM AgentSales
GROUP BY CAST(YEAR([DATE]) AS VARCHAR)+' '+CAST(MONTH([DATE]) AS VARCHAR), AGENT
ORDER BY 1
YRMON AGENT SALES
2021 1 Agent A 12
2021 1 Agent B 27
2021 2 Agent A 1
2021 2 Agent B 33
2021 3 Agent A 11
2021 3 Agent B 3
枢轴:
SELECT CAST(YEAR([DATE]) AS VARCHAR)+' '+CAST(MONTH([DATE]) AS VARCHAR) YRMON, [AGENT A], [AGENT B]
FROM AgentSales
PIVOT (SUM(SALES) FOR AGENT IN ([AGENT A], [AGENT B])) AS PIVOTTABLE
YRMON AGENT A AGENT B
2021 1 10 NULL
2021 1 2 NULL
2021 1 NULL 22
2021 1 NULL 5
2021 2 1 NULL
2021 2 NULL 33
2021 3 11 NULL
2021 3 NULL 3
我想用实际值代替 NULL。因此实际上每个 YearMon 应该只有 2 行。如何做到这一点?
预期结果:
YRMON AGENT A AGENT B
2021 1 12 27
2021 2 1 33
2021 3 11 3
看起来简单的条件聚合应该可以解决问题。
SELECT
FORMAT(EOMONTH([DATE]), 'yyyy MM') YRMON,
SUM(CASE WHEN AGENT = 'AGENT B' THEN SALES END) [AGENT B],
SUM(CASE WHEN AGENT = 'AGENT A' THEN SALES END) [AGENT A]
FROM AgentSales
GROUP BY EOMONTH([DATE])
ORDER BY EOMONTH([DATE]);
或者,如果您希望每一个都在单独的一行中,您可以添加一个行号并在其上分组
SELECT
FORMAT(EOMONTH([DATE]), 'yyyy MM') YRMON,
SUM(CASE WHEN AGENT = 'AGENT B' THEN SALES END) [AGENT B],
SUM(CASE WHEN AGENT = 'AGENT A' THEN SALES END) [AGENT A]
FROM (
SELECT *,
rn = ROW_NUMBER() OVER (PARTITION BY EOMONTH([DATE]), AGENT ORDER BY [DATE])
FROM AgentSales
) sales
GROUP BY EOMONTH([DATE]), rn
ORDER BY EOMONTH([DATE]), rn;
Grouping by
EOMONTH
is more performant than grouping by a string