博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
sql 行转列
阅读量:6823 次
发布时间:2019-06-26

本文共 2079 字,大约阅读时间需要 6 分钟。

  经典SQL问题: 行转列

0

学校里面记录成绩,每个人的选课不一样,而且以后会添加课程,所以不需要把所有课程当作列。数据库grade里面数据如下图,假定每个人姓名都不一样,作为主键。本文以MySQL为基础,其他数据库会有些许语法不同。

数据库数据:

处理后效果:

下面介绍三种方法:

方法一:

SELECTDISTINCT a.name, (SELECTscoreFROMgrade bWHEREa.name=b.nameANDb.course='语文')AS'语文', (SELECTscoreFROMgrade bWHEREa.name=b.nameANDb.course='数学')AS'数学', (SELECTscoreFROMgrade bWHEREa.name=b.nameANDb.course='英语')AS'英语' FROMgrade a

方法二:

SELECTname, SUM(CASE courseWHEN '语文'THENscoreEND)AS'语文', SUM(CASE courseWHEN '数学'THENscoreEND)AS'数学', SUM(CASE courseWHEN '英语'THENscoreEND)AS'英语' FROMgradeGROUPBYname

方法三:

DELIMITER && CREATE PROCEDURE sp_count() BEGIN #课程名称 DECLARE course_n VARCHAR(20); #所有课程数量 DECLARE count INT; #计数器 DECLARE i INT DEFAULT 0; #拼接SQL字符串 SET @s = 'SELECT name'; SET count = (SELECT  COUNT(distinct course) FROM grade); WHILE i < count DO SET course_n = (SELECT course FROM grade LIMIT i,1); SET @s = CONCAT(@s, ', SUM(CASE  course WHEN  ','\'', course_n,'\'',' THEN score END )',' AS ','\'',course_n,'\''); SET i = i+1; END WHILE; SET @s = CONCAT(@s, ' FROM grade GROUP BY name'); #用于调试 #SELECT @s; PREPARE stmt FROM @s; EXECUTE stmt; END &&   call sp_count();

方法分析:

第一种方法使用了表连接。

第二种使用了分组,对每个分组分别处理。
第三种使用了存储过程,其实是第二种方法的动态化,先计算出所有课程的数量,然后对每个分组进行课程查询。
很明显前两种方法属于硬编码,增加课程后就需要修改SQL。而第三种则没有这种问题。

Note:

MySQL中不能在一个存储过程中删除另一个存储过程,只能调用另一个存储过程

本来想在方法三里面写上:DROP PROCEDURE IF EXISTS sp_count();这是错误的。调试的时候如果写错了,只能手动删除了,也没找到好方法。

 

方法二还可以使用IF语句。

如下所示:

SELECT name, SUM(IF (course = '语文' , score , null ) ) as '语文', SUM(IF (course = '数学' , score , null ) ) as '数学', SUM(IF (course = '英语' , score , null ) ) as '英语 ' FROM grade GROUP BY name
  • IF(expr1,expr2,expr3),如果expr1是TRUE(expr1<>0且expr1<>NULL),那么IF()返回expr2,否则它返回expr3。IF()返回一个数字或字符串值,取决于它被使用的上下文。

 

 

 

 

 

 

 

 

 

 

create table shi
(
    语文 
int,
    数学 
int,
    英语 
int,
)
select *
from shi
select
(
case when 语文>=
80 then 
'
优秀
' when 语文>
60 then 
'
及格
' 
else 
'
不及格
' end) 
as 语文,
(
case when 数学>=
80 then 
'
优秀
' when 数学>
60 then 
'
及格
' 
else 
'
不及格
' end) 
as 数学,
(
case when 英语>=
80 then 
'
优秀
' when 英语>
60 then 
'
及格
' 
else 
'
不及格
' end) 
as 英语

from shi 

转载于:https://www.cnblogs.com/cf924823/p/5195161.html

你可能感兴趣的文章
简单工厂模式(C++)
查看>>
WinForm DataGridView分页功能
查看>>
正则表达式-字符类减法
查看>>
vs2008添加Ajax vs2008 Ajax配置
查看>>
UITableViewController与UIViewController中使用UITableView
查看>>
readonly vs. const [C#]
查看>>
温习数据结构之图的邻接矩阵的相关操作2011.10.22
查看>>
session cookie 原理2
查看>>
nginx下禁止访问robots.txt的设置方法
查看>>
常用的140个Windows XP设置 [转]
查看>>
431.chapter3.创建表,约束和用户自定义类型
查看>>
HOW TO : Install Eclipse with C/C++ in Ubuntu 12.04
查看>>
人生何处不选择
查看>>
报错:对一个或多个实体的验证失败。有关详细信息,请参阅“EntityValidationErrors”属性...
查看>>
ExtJs表单验证的方法总结
查看>>
Word Embedding与Word2Vec
查看>>
ObjectiveC基础教程(第2版)
查看>>
Android API学习 SoundPool 和 MediaPlayer
查看>>
topcoder srm 661 div1 -3
查看>>
NEWS: Symantec宣布Wise Package Studio将终止
查看>>