SET @sql = NULL; SELECT GROUP_CONCAT(DISTINCT CONCAT( 'MAX(CASE WHEN col_name = ''', col_name , ''' THEN value END) AS ', concat('`',col_name,'`') ) ) INTO @sql FROM ( SELECT DISTINCT col_name FROM your_table ) t; SET @query = CONCAT('SELECT id, ', @sql, ' FROM your_table GROUP BY id'); PREPARE stmt FROM @query; EXECUTE stmt; DEALLOCATE PREPARE stmt; 逐行翻译
时间: 2025-03-11 21:18:23 浏览: 41
好的,下面是对这段 SQL 代码的逐行解释和翻译:
### 1. 初始化变量
```sql
SET @sql = NULL;
```
**解释**: 将用户定义的会话变量 `@sql` 设置为 `NULL`。这个变量用于存储动态构建的部分查询字符串。
---
### 2. 构建列表达式
```sql
SELECT GROUP_CONCAT(DISTINCT CONCAT(
'MAX(CASE WHEN col_name = ''', col_name , ''' THEN value END) AS ', concat('`',col_name,'`')
)
) INTO @sql
FROM (
SELECT DISTINCT col_name FROM your_table
) t;
```
**分解及解释**:
- **内部子查询 (`t`)**
```sql
SELECT DISTINCT col_name FROM your_table
```
- 这里从 `your_table` 中提取唯一的 `col_name` 值列表。
- **外部查询**
```sql
SELECT GROUP_CONCAT(DISTINCT CONCAT(...))
```
- `CONCAT(...)`: 对每个独特的 `col_name` 创建一个新的字符串形式,类似于 `'MAX(CASE WHEN col_name = 'some_value' THEN value END) AS `some_value```.
- `DISTINCT`: 确保不会因为重复而产生多余的聚合计算.
- `GROUP_CONCAT(...)`: 把所有构造出来的列表达式的字符串连接成一个大的字符串,以便后续拼接完整 SQL.
- 最终结果会被赋给之前声明的 `@sql` 变量。
---
### 3. 组装完整的查询语句
```sql
SET @query = CONCAT('SELECT id, ', @sql, ' FROM your_table GROUP BY id');
```
**解释**: 使用 `CONCAT()` 函数把前面生成的列表达式插入到固定的框架内(即 `SELECT id,...FROM...GROUP BY id`),形成最终想要执行的大规模行转列查询命令,并将其存入另一个会话变量 `@query`.
---
### 4. 执行准备阶段
```sql
PREPARE stmt FROM @query;
```
**解释**: 预编译由上一步得到的 SQL 字符串作为预处理语句,并命名为 `stmt`. 这样做可以让数据库提前解析一次语法结构,在真正运行前就准备好最佳执行计划。
---
### 5. 执行实际查询
```sql
EXECUTE stmt;
```
**解释**: 正式地告诉 DBMS 开始执行已经预先配置好了的 `stmt` 语句块。此时才会真正读取数据并对它们应用转换规则。
---
### 6. 清理资源
```sql
DEALLOCATE PREPARE stmt;
```
**解释**: 解除对名为 `stmt` 的预处理语句对象的所有权引用。这是良好的实践习惯,能够释放内存空间和其他潜在占用的系统资源。
---
通过上述步骤,实现了将原始表中的多行记录按 ID 聚合并按照各个 `col_name` 分别展开成为新表里的单独列的过程。这种方式非常适合于那些事先不确定会有多少种不同类型的数据列需要展现出来的情形。
阅读全文
相关推荐














