行转列或列转行写法

两种方式:

/*	
实现行转列
a
name	objec	score
a		EN		89
a		CH		78
a		HO		99
b		EN		34
b		CH		88
b		HO		66
要求输出结果为:
name	EN	CH	HO
a		89	78	99
b		34	88	66
*/

USE tempdb
IF (SELECT 1 FROM sys.sysobjects WHERE name ='t' AND type='u') is NOT NULL 
DROP TABLE t


CREATE TABLE t
(
	NAME	CHAR(10),
	objec	CHAR(10),
	score	FLOAT
)
INSERT INTO t
VALUES('a','EN',89),('a','CH',78),('a','HO',99),('b','EN',34),('b','CH',88),('b','HO',66)

SELECT * FROM T

SELECT NAME ,MAX(CASE objec WHEN 'EN' THEN score ELSE 0 END ) EN,MAX(CASE objec WHEN 'CH' THEN score ELSE 0 END ) CH,MAX(CASE objec WHEN 'HO' THEN score ELSE 0 END ) HO
FROM t
GROUP BY NAME 
--=======================================================================================================================================================
/*	
实现行转列
a
name	objec	score
a		EN		89
a		CH		78
a		HO		99
b		EN		34
b		CH		88
b		HO		66
要求输出结果为:
name	objec		totalsorce
a		EN,CH,HO	266
b		EN,CH,HO	188
*/

USE tempdb
IF (SELECT 1 FROM sys.sysobjects WHERE name ='t' AND type='u') is NOT NULL 
DROP TABLE t

CREATE TABLE t
(
	NAME	CHAR(10),
	objec	CHAR(10),
	score	FLOAT
)
INSERT INTO t
VALUES('a','EN',89),('a','CH',78),('a','HO',99),('b','EN',34),('b','CH',88),('b','HO',66)

SELECT * FROM T

--为了去除objec中的最后一个逗号,插入一个临时表,并使用substring处理
SELECT name ,(SELECT LTRIM(RTRIM(objec))+',' FROM T WHERE objec=t.objec FOR XML PATH('')) objec,SUM(temp.score) totalscroe INTO #tmp
FROM T temp
GROUP BY name 


SELECT NAME ,SUBSTRING(objec,0,LEN(objec)-1) objec ,totalscroe
FROM #tmp


<think>嗯,用户问的是MySQL中如何实现转行,也就是PIVOT的反操作,行转列。首先,我得确认MySQL本身是否支持PIVOT语法。根据我记得,MySQL不像SQL Server那样直接支持PIVOT和UNPIVOT操作。用户提到的参考引用里,引用[1]提到了UNPIVOT语法,但可能是在其他数据库中的用法,比如SQL Server。引用[2]提到了动态行转列,但用户需要的是转行,也就是UNPIVOT。 接下来,用户可能需要的是将多个转换为行记录。比如,学生表中的各科成绩(数学、语文、英语)转换为行,每行显示一个科目的成绩。这时候,通常的方法是使用UNION ALL者动态SQL。不过,MySQL没有内置的UNPIVOT函数,所以需要手动处理。 首先,静态转行的话,可以用UNION ALL。例如,每个科目单独SELECT出来,然后合并。这种方法适合已知名的情况,但如果很多者动态变化,就不方便了。 然后是动态SQL方法,用户提到的引用[2]是关于动态行转列,但思路类似。动态生成SQL语句,通过CONCAT拼接名,然后执行预处理语句。这里需要从information_schema中获取表的信息,然后构造UNION ALL的语句。 需要注意的是,动态SQL可能会比较复杂,需要处理变量和预处理语句。另外,用户可能需要示例代码,所以应该给出具体的例子,比如学生成绩表的转换。 同时,用户提供的引用[3]中有插入学生数据的例子,包含数学、语文、英语的成绩,这正好可以作为示例数据。所以可以基于这个例子来展示如何将这三个科目的转换为行。 总结一下,回答应该分两部分:静态转行使用UNION ALL,动态转行使用动态SQL。并且给出具体的示例,引用用户提供的例子中的数据。同时,要指出MySQL没有直接的PIVOT语法,需要使用其他方法替代。</think>在MySQL中实现转行(即行转列UNPPVOT操作),可以通过以下两种方法实现: ### 一、静态转行(适用于已知名) ```sql SELECT stuid, stunm, 'math' AS subject, math AS score FROM Student UNION ALL SELECT stuid, stunm, 'chinese', chinese FROM Student UNION ALL SELECT stuid, stunm, 'english', english FROM Student ORDER BY stuid, subject; ``` *说明:* 此方法手动指定需要转换的名(math/chinese/english),生成科目-分数对应关系[^3]。 ### 二、动态转行(适用于未知名) ```sql SET @sql = NULL; SELECT GROUP_CONCAT(DISTINCT CONCAT('SELECT stuid, stunm, ''', COLUMN_NAME, ''' AS subject, ', COLUMN_NAME, ' AS score FROM Student') ) INTO @sql FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'Student' AND COLUMN_NAME NOT IN ('stuid', 'stunm', 'birthdate', 'gender'); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; ``` *说明:* 通过`INFORMATION_SCHEMA`动态获取名,自动生成UNION ALL查询语句[^2]。 ### 示例数据转换效果 原始数据格式: | stuid | stunm | math | chinese | english | |-------|-------|-----|---------|---------| | 01 | 赵雷 | 80 | 90 | 99 | 转换后结果: | stuid | stunm | subject | score | |-------|-------|----------|-------| | 01 | 赵雷 | math | 80 | | 01 | 赵雷 | chinese | 90 | | 01 | 赵雷 | english | 99 | ### 对比说明 1. **静态方法**适合固定结构的表,查询效率更高 2. **动态方法**适合经常变化的场景,但需要执行预处理语句
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值