死磕:SQL行转列汇总(全网最全最详细)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了死磕:SQL行转列汇总(全网最全最详细)相关的知识,希望对你有一定的参考价值。

参考技术A

阅读目录

PIVOT 用于将列值旋转为列名(即行转列),在 SQL Server 2000可以用聚合函数配合CASE语句实现

PIVOT 的一般语法是:PIVOT(聚合函数(列) FOR 列 in (…) )AS P

注意:PIVOT、UNPIVOT是SQL Server 2005 的语法,使用需修改数据库兼容级别(在数据库属性->选项->兼容级别改为 90 )

SQL2008 中可以直接使用

完整语法:

View Code

UNPIVOT 用于将列明转为列值(即列转行),在SQL Server 2000可以用UNION来实现

姓名 课程 分数

---------- ---------- -----------

张三 语文 74

张三 数学 83

张三 物理 93

李四 语文 74

李四 数学 84

李四 物理 94

姓名 语文 数学 物理

---------- ----------- ----------- -----------

李四 74 84 94

张三 74 83 93

姓名 语文 数学 物理 总分 平均分

---------- ----------- ----------- ----------- -----------

李四 74 84 94 252 84.00

张三 74 83 93 250 83.33

姓名 语文 数学 物理

---------- ----------- ----------- -----------

张三 74 83 93

李四 74 84 94

姓名 课程 分数

---------- ---- -----------

李四 语文 74

李四 数学 84

李四 物理 94

张三 语文 74

张三 数学 83

张三 物理 93

最后给大家分享Spring系列的学习笔记和面试题,包含spring面试题、spring cloud面试题、spring boot面试题、spring教程笔记、spring boot教程笔记、最新阿里巴巴开发手册(63页PDF总结)、2022年Java面试手册。一共整理了1184页PDF文档。私信博主(777)领取,祝大家更上一层楼!!!

原文作者:王思明

原文出处:http://www.cnblogs.com/maanshancss/

SQL行转列

一、使用场景

  当系统中有汇总和明细的需求时,一般通过SQL来实现,汇总 就是 根据条件显示出全部的数据,明细 就是 一条汇总对应的详细信息。

  行转列通常用于实现明细的时候。

二、举例实现

  1.当表中不存在id时:

  1). 新建表student,姓名(name)、学科(subject)、成绩(score)

create table student(name nvarchar(20),subject nvarchar(20),score int)

  2). 插入数据

insert into student values(\'张三\',\'语文\',80),(\'张三\',\'数学\',90),(\'张三\',\'英语\',75) 
insert into student values(\'李四\',\'语文\',75),(\'李四\',\'数学\',93),(\'李四\',\'英语\',56) 
insert into student values(\'王五\',\'语文\',87),(\'王五\',\'数学\',67),(\'王五\',\'英语\',83) 

  3). 方式一实现:使用case when ... then ... end

select name,
    max(case subject when \'语文\' then score else 0 end) \'语文\',
    max(case subject when \'数学\' then score else 0 end) \'数学\',
    max(case subject when \'英语\' then score else 0 end) \'英语\',
    SUM(score)  as \'总分\',
    cast(AVG(cast(score as decimal(10,2))) as decimal(10,2)) as \'平均分\'
from student group by name

  

  4) 方式二实现:自己和自己关联

select 
    a.name,a.score,b.score,c.score,(a.score+b.score+c.score) \'总分\',CAST((a.score+b.score+c.score)/3.0 as decimal(5,2)) \'平均分\' 
from student a,student b,student c 
where a.name = b.name and b.name = c.name and a.subject=\'语文\' and b.subject=\'数学\' and c.subject=\'英语\'

  

  5) 方式三实现:使用pivot

select * from student pivot(max(score) for subject in (语文,数学,英语))a 

   

  2.当表中存在id时,

  1). 新建表tb_student,序号(id)、姓名(name)、学科(subject)、成绩(score)

create table tab_student(id int,name nvarchar(20),subject nvarchar(20),score int)

  2). 插入数据:

insert into tab_student values (1,\'张三\',\'语文\',76),(2,\'张三\',\'数学\',85),(3,\'张三\',\'英语\',67)
insert into tab_student values (3,\'李四\',\'语文\',87),(4,\'李四\',\'数学\',32),(5,\'李四\',\'英语\',85)
insert into tab_student values (6,\'王五\',\'语文\',83),(7,\'王五\',\'数学\',90),(8,\'王五\',\'英语\',80)

  3) 方式一实现:使用 case when 

select name,MAX(case subject when \'语文\' then score else 0 end) as \'语文\',
       MAX(case subject when \'数学\' then score else 0 end) as  \'数学\',
       MAX(case subject when \'英语\' then score else 0 end) as  \'英语\',
       SUM(score) \'总数\',
       cast(AVG(CAST(score as decimal(10,2))) as decimal(10,2)) \'平均数\' 
from tab_student group by name

  

  4). 方式二实现:自己关联自己

select 
    a.name,a.score,b.score,c.score,(a.score+b.score+c.score) \'总分\',CAST((a.score+b.score+c.score)/3.0 as decimal(5,2)) \'平均分\' 
from tab_student a,tab_student b,tab_student c 
where a.name = b.name and b.name = c.name and a.subject=\'语文\' and b.subject=\'数学\' and c.subject=\'英语\'

   

   5). 方式三实现不了:pivot

select * from tab_student pivot(
    max(score) for subject in (语文,数学,英语)
)a 

   

 

以上是关于死磕:SQL行转列汇总(全网最全最详细)的主要内容,如果未能解决你的问题,请参考以下文章

Hive sql 行转列列转行全网最清楚

SQL语句行转列

【求助】有关oracle 动态行转列

SQL行转列经典例子(转载)

sql 行转列

sql server 2012 行转列