✅MySQL如何实现行转列和列转行?
典型回答
行转列
所谓行转列,就是假设有如下数据表 sales:
| id | year | product | sales |
|---|---|---|---|
| 1 | 2020 | A | 100 |
| 2 | 2020 | B | 200 |
| 3 | 2021 | A | 150 |
| 4 | 2021 | B | 300 |
要将 product 列的不同值(A 和 B)变为列标题,year 作为行标题,生成如下结果:
| year | A | B |
|---|---|---|
| 2020 | 100 | 200 |
| 2021 | 150 | 300 |
这里,可以使用CASE WHEN THEN 用来根据条件为每个 product 创建一列,并通过 SUM 聚合同一年份的销售数据,达到行转列的效果。
SELECT
year,
SUM(CASE WHEN product = 'A' THEN sales ELSE 0 END) AS A,
SUM(CASE WHEN product = 'B' THEN sales ELSE 0 END) AS B
FROM sales
GROUP BY year;简答解释下:
**SUM(CASE WHEN product = 'A' THEN sales ELSE 0 END) AS A**:- 使用
CASE WHEN判断product是否为A:- 如果是
A,则返回该行的sales值。 - 如果不是
A,则返回0。
- 如果是
- 然后,
SUM函数将每个year内所有product = 'A'的sales值加总,最终得到该year对应的A产品总销售额。
还可以使用IF实现类似CASE WHEN的功能:
SELECT
year,
SUM(IF(product = 'A', sales, 0)) AS A,
SUM(IF(product = 'B', sales, 0)) AS B
FROM sales
GROUP BY year;列转行
所谓列转行,假设有如下数据表 sales_data :
| year | A | B |
|---|---|---|
| 2020 | 100 | 200 |
| 2021 | 150 | 300 |
转成如下格式结构:
| year | product | sales |
|---|---|---|
| 2020 | A | 100 |
| 2020 | B | 200 |
| 2021 | A | 150 |
| 2021 | B | 300 |
通常是使用UNION ALL 实现:
SELECT
year,
'A' AS product,
A AS sales
FROM sales_data
UNION ALL
SELECT
year,
'B' AS product,
B AS sales
FROM sales_data;
ORDER BY year, product;- 第一个
SELECT子查询提取了A列的数据,并将A作为product值: - 输出行:
(2020, 'A', 100)和(2021, 'A', 150)。 - 第二个
SELECT子查询提取了B列的数据,并将B作为product值: - 输出行:
(2020, 'B', 200)和(2021, 'B', 300)。 UNION ALL将两组查询结果合并。