做该做的 发表于 2024-7-6 05:20:56

MySQL中实现行列转换的操作示例

在 MySQL 中进行行列转换(即,将某些列转换为行或将某些行转换为列)通常涉及使用条件逻辑和聚合函数。虽然 MySQL 没有像 Oracle/SQL Server 中的 PIVOT 和 UNPIVOT 那样的直接功能,但你可以通过结合 CASE 语句、UNION 或 UNION ALL、以及 GROUP BY 等来实现这些转换。

1、行转列的操作

在 MySQL 中,并没有内置的 PIVOT 函数,如 Oracle/SQL Server 中那样。但是,你可以使用条件聚合或 CASE 语句来模拟 PIVOT 操作。
以下是一个简单的示例,说明如何在 MySQL 中模拟 PIVOT。
假设你有一个名为 t_sales 的表,它记录了销售数据,结构如下:
CREATE TABLE t_sales (
    id int primary key auto_increment,
    col_year INT,
    product VARCHAR(255),
    amount DECIMAL(10, 2)
);

INSERT INTO t_sales (col_year, product, amount) VALUES
(2020, 'A001', 100),
(2020, 'B001', 120),
(2021, 'A001', 150),
(2021, 'B001', 150),
(2022, 'A001', 260),
(2022, 'B001', 240),
(2023, 'B001', 330),
(2024, 'A001', 440);

(root@localhost:mysql.sock)>select * from t_sales;
+----+----------+---------+--------+
| id | col_year | product | amount |
+----+----------+---------+--------+
|1 |   2020 | A001    | 100.00 |
|2 |   2020 | B001    | 120.00 |
|3 |   2021 | A001    | 150.00 |
|4 |   2021 | B001    | 150.00 |
|5 |   2022 | A001    | 260.00 |
|6 |   2022 | B001    | 240.00 |
|7 |   2023 | B001    | 330.00 |
|8 |   2024 | A001    | 440.00 |
+----+----------+---------+--------+
8 rows in set (0.00 sec)现在,假设你想要将产品列 (product) 转换为列标题,并为每个年份和产品显示销售额。在 Oracle/SQL Server 中,你可以使用 PIVOT 来实现这一点。但在 MySQL 中,你可以这样做:
SELECT   
    col_year,
    SUM(CASE WHEN product = 'A001' THEN amount ELSE 0 END) AS 'A_product',
    SUM(CASE WHEN product = 'B001' THEN amount ELSE 0 END) AS 'B_product'
FROM t_sales
GROUP BY col_year;

(root@localhost:mysql.sock)>SELECT   
    ->   col_year,
    ->   SUM(CASE WHEN product = 'A001' THEN amount ELSE 0 END) AS 'A_product',
    ->   SUM(CASE WHEN product = 'B001' THEN amount ELSE 0 END) AS 'B_product'
    -> FROM t_sales
    -> GROUP BY col_year;
   
-- 这将返回以下结果
+----------+-----------+-----------+
| col_year | A_product | B_product |
+----------+-----------+-----------+
|   2020 |    100.00 |    120.00 |
|   2021 |    150.00 |    150.00 |
|   2022 |    260.00 |    240.00 |
|   2023 |      0.00 |    330.00 |
|   2024 |    440.00 |      0.00 |
+----------+-----------+-----------+
5 rows in set (0.00 sec)这就是在 MySQL 中模拟 PIVOT 的方法。对于更复杂的转换或更多的产品,你可能需要扩展 CASE 语句来包含更多的条件。

2、列转行的操作

在 MySQL 中,没有直接的 UNPIVOT 操作,因为 UNPIVOT 是 SQL Server 和 Oracle 等数据库系统中的功能,用于将多列转换为多行。但是,你可以使用 MySQL 的查询技巧来模拟 UNPIVOT 操作。
假设你有一个类似 PIVOT 后的结果集,并且你想要将其转换回原始的多行格式,你可以使用 UNION ALL 或 UNION(取决于是否要消除重复行)来模拟 UNPIVOT。
以下是一个示例,说明如何在 MySQL 中模拟 UNPIVOT 操作:
假设你有一个 t_pivoted_sales 表,它是通过 PIVOT(或上述的 MySQL 模拟方法)得到的:
CREATE TABLE t_pivoted_sales (
    id int primary key auto_increment,
    col_year INT,
    A_product DECIMAL(18, 2),
    B_product DECIMAL(18, 2)
);

INSERT INTO t_pivoted_sales (col_year, A_product, B_product) VALUES
(2020, 100.00, 120.0),
(2021, 150.00, 150.00),
(2022, 260.00, 240.00),
(2023, 0.00, 330.00),
(2024, 440.00, 0.00);

(root@localhost:mysql.sock)>select * from t_pivoted_sales;
+----+----------+-----------+-----------+
| id | col_year | A_product | B_product |
+----+----------+-----------+-----------+
|1 |   2020 |    100.00 |    120.00 |
|2 |   2021 |    150.00 |    150.00 |
|3 |   2022 |    260.00 |    240.00 |
|4 |   2023 |      0.00 |    330.00 |
|5 |   2024 |    440.00 |      0.00 |
+----+----------+-----------+-----------+
5 rows in set (0.00 sec)现在,你想要将 A_product 和 B_product 列转换回多行格式,其中有一个额外的列product来表示产品(A_product 或 B_product)。你可以使用以下查询来模拟 UNPIVOT:
SELECT col_year, 'A_product' AS product, A_product AS amount FROM t_pivoted_sales
union all
SELECT col_year, 'B_product' AS product, B_product AS amount FROM t_pivoted_sales
order by col_year;这将返回以下结果

这就是在 MySQL 中模拟 UNPIVOT 操作的方法。通过为每个你想要“unpivot”的列创建一个 SELECT 语句,并使用 UNION ALL 将它们组合在一起,你可以得到期望的多行格式结果。
到此这篇关于MySQL中实现行列转换的操作示例的文章就介绍到这了,更多相关MySQL行列转换内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

来源:https://www.jb51.net/database/3228757xk.htm
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: MySQL中实现行列转换的操作示例