复杂的sql 行转列揭秘

来源:互联网 发布:php fpm 重启 编辑:程序博客网 时间:2024/06/05 09:50

先看数据库表

CREATE TABLE MonthStats (
  DevNo   int NOT NULL,          -- 设备编号
  Time   smalldatetime NOT NULL PRIMARY KEY (DevNo, Time), -- 数据时间 (年月)
  TotalTime  int,   -- 总运行时间 (分钟)
  RegularTime  int,   -- 合格时间(分钟)
  RegularRate  float,   -- 合格率(%)
  OverHighTime int,   -- 超高时间(分钟)
  OverHighRate float,   -- 超高率(%)
  OverLowTime  int,   -- 超低时间(分钟)
  OverLowRate  float,   -- 超低率(%)
  PwDnTime  int,   -- 停电时间(分钟)
  PwDnCnt   int,   -- 停电次数
  AverU   float,   -- 平均电压(V)
  MaxU   float,   -- 最高电压(V)
  MinU   float,   -- 最低电压(V)
  AverHarm  float,   -- 平均总谐波畸变率(%)
  MaxHarm   float,   -- 最大总谐波畸变率(%)
  MinHarm   float,   -- 最小总谐波畸变率(%)
  AverFreq  float,   -- 平均频率(Hz)
  MaxVoltStamp smalldatetime, -- 最高电压出现时刻
  MinVoltStamp smalldatetime, -- 最低电压出现时刻
  MaxHarmStamp smalldatetime, -- 最大总谐波畸变率出现时刻
  MinHarmStamp smalldatetime -- 最小总谐波畸变率出现时刻
     SafeTimeHarm int,   -- 谐波合格时间(分钟)
  SafeRateHarm float,   -- 谐波合格率(%)
  WarmTimeHarm int,   -- 谐波超限时间(分钟)
  WarmRateHarm float,   -- 谐波超限率(%)
  
  )

 

测试语句:

insert into MonthStats
values(1,'2010-01-01 00:01:00',16,20,1.1,3,2.1,6,5.5,8,1,18.5,15.3,200.0,155.3,23.5,65.4,43.6,'2010-11-23 10:00:00','2010-12-03 11:00:00','2010-12-15 18:00:00','2010-12-18 19:00:00',86400,90,1,0.1)
insert into MonthStats
values(2,'2010-02-02 00:02:00',16,20,1.1,3,2.1,6,5.5,8,1,18.5,15.3,200.0,155.3,23.5,65.4,43.6,'2010-11-23 10:30:00','2010-12-03 11:43:00','2010-12-15 18:00:00','2010-12-18 19:00:00',86400,91,1,0.1)
insert into MonthStats
values(7,'2010-03-03 00:03:00',16,20,1.1,3,2.1,6,5.5,8,1,18.5,15.3,200.0,155.3,23.5,65.4,43.6,'2010-11-23 10:50:00','2010-12-03 11:03:00','2010-12-15 18:00:00','2010-12-18 19:00:00',86400,92,1,0.1)
insert into MonthStats
values(11,'2010-04-04 00:04:00',16,20,1.1,3,2.1,6,5.5,8,1,18.5,15.3,200.0,155.3,23.5,65.4,43.6,'2010-11-23 11:34:00','2010-12-03 14:40:00','2010-12-15 18:00:00','2010-12-18 19:00:00',86400,93,1,0.1)
insert into MonthStats
values(18,'2010-05-05 00:05:00',16,20,1.1,3,2.1,6,5.5,8,1,18.5,15.3,200.0,155.3,23.5,65.4,43.6,'2010-11-23 11:50:00','2010-12-03 16:04:00','2010-12-15 18:00:00','2010-12-18 19:00:00',86400,94,1,0.1)
insert into MonthStats
values(1,'2010-06-06 00:06:00',16,20,1.1,3,2.1,6,5.5,8,1,18.5,15.3,200.0,155.3,23.5,65.4,43.6,'2010-11-23 13:01:00','2010-12-03 17:07:00','2010-12-15 18:00:00','2010-12-18 19:00:00',86400,95,1,0.1)
insert into MonthStats
values(1,'2010-07-07 00:07:00',16,20,1.1,3,2.1,6,5.5,8,1,18.5,15.3,200.0,155.3,23.5,65.4,43.6,'2010-11-23 13:20:00','2010-12-03 18:20:00','2010-12-15 18:00:00','2010-12-18 19:00:00',86400,96,1,0.1)
insert into MonthStats
values(2,'2010-08-07 00:07:00',16,20,1.1,3,2.1,6,5.5,8,1,18.5,15.3,200.0,155.3,23.5,65.4,43.6,'2010-11-23 13:20:00','2010-12-03 18:20:00','2010-12-15 18:00:00','2010-12-18 19:00:00',86400,96,1,0.1)
insert into MonthStats
values(2,'2010-09-07 00:07:00',16,20,1.1,3,2.1,6,5.5,8,1,18.5,15.3,200.0,155.3,23.5,65.4,43.6,'2010-11-23 13:20:00','2010-12-03 18:20:00','2010-12-15 18:00:00','2010-12-18 19:00:00',86400,96,1,0.1)
insert into MonthStats
values(7,'2010-10-07 00:07:00',16,20,1.1,3,2.1,6,5.5,8,1,18.5,15.3,200.0,155.3,23.5,65.4,43.6,'2010-11-23 13:20:00','2010-12-03 18:20:00','2010-12-15 18:00:00','2010-12-18 19:00:00',86400,96,1,0.1)
insert into MonthStats
values(11,'2010-11-07 00:07:00',16,20,1.1,3,2.1,6,5.5,8,1,18.5,15.3,200.0,155.3,23.5,65.4,43.6,'2010-11-23 13:20:00','2010-12-03 18:20:00','2010-12-15 18:00:00','2010-12-18 19:00:00',86400,96,1,0.1)
insert into MonthStats
values(18,'2010-12-07 00:07:00',16,20,1.1,3,2.1,6,5.5,8,1,18.5,15.3,200.0,155.3,23.5,65.4,43.6,'2010-11-23 13:20:00','2010-12-03 18:20:00','2010-12-15 18:00:00','2010-12-18 19:00:00',86400,96,1,0.1)
insert into MonthStats
values(19,'2011-01-07 00:07:00',17,20,1.1,3,2.1,6,5.5,8,1,18.5,15.3,200.0,155.3,23.5,65.4,43.6,'2010-11-23 13:20:00','2010-12-03 18:20:00','2010-12-15 18:00:00','2010-12-18 19:00:00',86400,96,1,0.1)

这blog怎么不可以插入sql Code:很无语.

 

现在根据数据时间进行行转列,想把它显示成这种效果

 

思路:怎么处理了?

1,先要把time 字段 截取 成 年月这种格式,这里我做的是动态转换 列名 ,假设一年中只出现只有一条记录,那么

表拆分也只有一个列,如:2011-01-01 08:01:01 变成201101月。

 

2,在这张表的结构中有很多类型,特别的是里面有几个字段是 时间类型,这种类型搞起来很恶心。

还有一点在做合计时,要把所有类型都转换字符串,为什么这样搞?

原因是在衔接表时,如果用一个聚合函数sum()统计出来的是int或float..等,你在哪一列中在搞个 时间类型,

就出出现算法溢出等异常。

 

3,这里我加了一些难度,

[总计]列

最高电压 出现,这样对应的最高电压出现时刻(时间)就在对应的对应max(最高电压)下面

 top 1是防止最高电压都是一样只取其中一条

select top 1 [MaxVoltStamp] from MonthStats where DevNo=1 and MaxU=(select max(MaxU) from MonthStats where DevNo=1)

通过这种话得到最高电压出现时间,

下面还有最低电压,最高谐波等

 

过程:

IF OBJECT_ID('PP')IS NOT NULL DROP PROC PP
GO 
create proc pp
    @devNo int,--设备号
    @year varchar(4)--年份
AS

--拼接字符串
declare @strTotalTime varchar(2000),-- 总运行时间 (分钟)
@strRegularTime varchar(2000),      -- 合格时间(分钟)
@strRegularRate varchar(2000),  -- 合格率(%)
@strOverHighTime varchar(2000),  -- 超高时间(分钟)
@strOverHighRate varchar(2000),  -- 超高率(%)
@strOverLowTime varchar(2000),  -- 超低时间(分钟)
@strOverLowRate varchar(2000),  -- 超低率(%)
@strPwDnTime varchar(2000),   -- 停电时间(分钟)
@strPwDnCnt varchar(2000),   -- 停电次数
@strAverU varchar(2000),   -- 平均电压(V)
@strMaxU varchar(2000),       -- 最高电压(V)
@strMinU varchar(2000),       -- 最低电压(V)
@strAverHarm varchar(2000),   -- 平均总谐波畸变率(%)
@strMaxHarm varchar(2000),   -- 最大总谐波畸变率(%)
@strMinHarm varchar(2000),   -- 最小总谐波畸变率(%)
@strAverFreq varchar(2000),   -- 平均频率(Hz)
@strMaxVoltStamp varchar(2000),     -- 最高电压出现时刻
@strMinVoltStamp varchar(2000),     -- 最低电压出现时刻
@strMaxHarmStamp varchar(2000),     -- 最大总谐波畸变率出现时刻
@strMinHarmStamp varchar(2000),     -- 最小总谐波畸变率出现时刻
@strSafeTimeHarm varchar(2000),  -- 谐波合格时间(分钟)
@strSafeRateHarm varchar(2000),  -- 谐波合格率(%)
@strWarmTimeHarm varchar(2000),  -- 谐波超限时间(分钟)
@strWarmRateHarm varchar(2000)  -- 谐波超限率(%)

--时间转换列名
select @strTotalTime=ISNULL(@strTotalTime+',','')+'SUM(case when CONVERT(varchar(6),[Time],112)='''+日期+''' then TotalTime ELSE 0 END) AS ['+日期+'月]',
@strRegularTime=ISNULL(@strRegularTime+',','')+'SUM(case when CONVERT(varchar(6),[Time],112)='''+日期+''' then RegularTime  ELSE 0 END) AS ['+日期+'月]',
@strRegularRate=ISNULL(@strRegularRate+',','')+'SUM(case when Convert(varchar(6),[Time],112)='''+日期+''' then RegularRate ElSE 0 END ) AS ['+日期+'月]',
@strOverHighTime=ISNULL(@strOverHighTime+',','')+'SUM(case when Convert(varchar(6),[Time],112)='''+日期+''' then OverHighTime ElSE 0 END ) AS ['+日期+'月]',
@strOverHighRate=ISNULL(@strOverHighRate+',','')+'SUM(case when Convert(varchar(6),[Time],112)='''+日期+''' then OverHighRate ElSE 0 END ) AS ['+日期+'月]',
@strOverLowTime=ISNULL(@strOverLowTime+',','')+'SUM(case when Convert(varchar(6),[Time],112)='''+日期+''' then OverLowTime ElSE 0 END ) AS ['+日期+'月]',
@strOverLowRate=ISNULL(@strOverLowRate+',','')+'SUM(case when Convert(varchar(6),[Time],112)='''+日期+''' then OverLowRate ElSE 0 END ) AS ['+日期+'月]',
@strPwDnTime=ISNULL(@strPwDnTime+',','')+'SUM(case when Convert(varchar(6),[Time],112)='''+日期+''' then PwDnTime ElSE 0 END ) AS ['+日期+'月]',
@strPwDnCnt=ISNULL(@strPwDnCnt+',','')+'SUM(case when Convert(varchar(6),[Time],112)='''+日期+''' then PwDnCnt ElSE 0 END ) AS ['+日期+'月]',
@strAverU=ISNULL(@strAverU+',','')+'SUM(case when Convert(varchar(6),[Time],112)='''+日期+''' then AverU ElSE 0 END ) AS ['+日期+'月]',
@strMaxU=ISNULL(@strMaxU+',','')+'SUM(case when Convert(varchar(6),[Time],112)='''+日期+''' then MaxU ElSE 0 END ) AS ['+日期+'月]',
@strMinU=ISNULL(@strMinU+',','')+'SUM(case when Convert(varchar(6),[Time],112)='''+日期+''' then MinU ElSE 0 END ) AS ['+日期+'月]',
@strAverHarm=ISNULL(@strAverHarm+',','')+'SUM(case when Convert(varchar(6),[Time],112)='''+日期+''' then AverHarm ElSE 0 END ) AS ['+日期+'月]',
@strMaxHarm=ISNULL(@strMaxHarm+',','')+'SUM(case when Convert(varchar(6),[Time],112)='''+日期+''' then MaxHarm ElSE 0 END ) AS ['+日期+'月]',
@strMinHarm=ISNULL(@strMinHarm+',','')+'SUM(case when Convert(varchar(6),[Time],112)='''+日期+''' then MinHarm ElSE 0 END ) AS ['+日期+'月]',
@strAverFreq=ISNULL(@strAverFreq+',','')+'SUM(case when Convert(varchar(6),[Time],112)='''+日期+''' then AverFreq ElSE 0 END ) AS ['+日期+'月]',
@strMaxVoltStamp=ISNULL(@strMaxVoltStamp+',','')+'SUM(case when Convert(varchar(6),[Time],112)='''+日期+''' then Convert(varchar(12),MaxVoltStamp,112) ElSE 0 END) AS ['+日期+'月]',
@strMinVoltStamp=ISNULL(@strMinVoltStamp+',','')+'SUM(case when Convert(varchar(6),[Time],112)='''+日期+''' then Convert(varchar(12),MinVoltStamp,112) ElSE 0 END) AS ['+日期+'月]',
@strMaxHarmStamp=ISNULL(@strMaxHarmStamp+',','')+'SUM(case when Convert(varchar(6),[Time],112)='''+日期+''' then Convert(varchar(12),MaxHarmStamp,112) ElSE 0 END) AS ['+日期+'月]',
@strMinHarmStamp=ISNULL(@strMinHarmStamp+',','')+'SUM(case when Convert(varchar(6),[Time],112)='''+日期+''' then Convert(varchar(12),MinHarmStamp,112) ElSE 0 END) AS ['+日期+'月]',
@strSafeTimeHarm=ISNULL(@strSafeTimeHarm+',','')+'SUM(case when Convert(varchar(6),[Time],112)='''+日期+''' then SafeTimeHarm ElSE 0 END ) AS ['+日期+'月]',
@strSafeRateHarm=ISNULL(@strSafeRateHarm+',','')+'SUM(case when Convert(varchar(6),[Time],112)='''+日期+''' then SafeRateHarm ElSE 0 END ) AS ['+日期+'月]',
@strWarmTimeHarm=ISNULL(@strWarmTimeHarm+',','')+'SUM(case when Convert(varchar(6),[Time],112)='''+日期+''' then WarmTimeHarm ElSE 0 END ) AS ['+日期+'月]',
@strWarmRateHarm=ISNULL(@strWarmRateHarm+',','')+'SUM(case when Convert(varchar(6),[Time],112)='''+日期+''' then WarmRateHarm ElSE 0 END ) AS ['+日期+'月]'
from (select distinct CONVERT(varchar(6),[Time],112)AS 日期 from MonthStats where [Time] like'%'+@year+'%')t--模糊查询某年


 --合并表,合计全部是字符串
 EXEC(
'SELECT DevNo,'+@strTotalTime +',Convert(varchar,sum(TotalTime)) 合计 FROM MonthStats whereDevNo='+@devNo+' group by DevNo
  union all
 SELECT  DevNo,' +@strRegularTime+',Convert(varchar,sum(RegularTime)) 合计 FROM MonthStats whereDevNo='+@devNo+' group by DevNo
 union all
 SELECT  DevNo,' +@strRegularRate+',Convert(varchar,sum(RegularRate)) 合计 FROM MonthStats whereDevNo='+@devNo+' group by DevNo
  union all
 SELECT  DevNo,' +@strOverHighTime+',Convert(varchar,sum(OverHighTime)) 合计 FROM MonthStats whereDevNo='+@devNo+' group by DevNo
  union all
 SELECT  DevNo,' +@strOverHighRate+',Convert(varchar,sum(OverHighRate)) 合计 FROM MonthStats whereDevNo='+@devNo+' group by DevNo
  union all
 SELECT  DevNo,' +@strOverLowTime+',Convert(varchar,sum(OverLowTime)) 合计 FROM MonthStats whereDevNo='+@devNo+' group by DevNo
  union all
 SELECT  DevNo,' +@strOverLowRate+',Convert(varchar,sum(OverLowRate)) 合计 FROM MonthStats whereDevNo='+@devNo+' group by DevNo
  union all
 SELECT  DevNo,' +@strPwDnTime+',Convert(varchar,sum(PwDnTime)) 合计 FROM MonthStats whereDevNo='+@devNo+' group by DevNo
  union all
 SELECT  DevNo,' +@strPwDnCnt+',Convert(varchar,sum(PwDnCnt)) 合计 FROM MonthStats whereDevNo='+@devNo+' group by DevNo
  union all
 SELECT  DevNo,' +@strAverU+',Convert(varchar,sum(AverU)) 合计 FROM MonthStats whereDevNo='+@devNo+' group by DevNo
  union all
 SELECT  DevNo,' +@strMaxU+',Convert(varchar,sum(MaxU)) 合计 FROM MonthStats whereDevNo='+@devNo+' group by DevNo
 union all
 SELECT  DevNo,' +@strMinU+',Convert(varchar,sum(MinU)) 合计 FROM MonthStats whereDevNo='+@devNo+' group by DevNo
 union all
 SELECT  DevNo,' +@strAverHarm+',Convert(varchar,sum(AverHarm)) 合计 FROM MonthStats whereDevNo='+@devNo+' group by DevNo
 union all
 SELECT  DevNo,' +@strMaxHarm+',Convert(varchar,sum(MaxHarm)) 合计 FROM MonthStats whereDevNo='+@devNo+' group by DevNo
 union all
 SELECT  DevNo,' +@strMinHarm+',Convert(varchar,sum(MinHarm)) 合计 FROM MonthStats whereDevNo='+@devNo+' group by DevNo
 union all
 SELECT  DevNo,' +@strAverFreq+',Convert(varchar,sum(AverFreq)) 合计 FROM MonthStats whereDevNo='+@devNo+' group by DevNo
 union all
 SELECT  DevNo, '+@strMaxVoltStamp+',Convert(varchar,(select top 1 [MaxVoltStamp] from MonthStats whereDevNo='+@devNo+' and MaxU=(select max(MaxU) from MonthStats whereDevNo='+@devNo+')),112) 合计 FROM MonthStats whereDevNo='+@devNo+' group by DevNo
  union all
 SELECT  DevNo, '+@strMinVoltStamp+',Convert(varchar,(select top 1 [MinVoltStamp] from MonthStats whereDevNo='+@devNo+' and MinU=(select min(MinU) from MonthStats whereDevNo='+@devNo+')),112) 合计 FROM MonthStats whereDevNo='+@devNo+' group by DevNo
  union all
 SELECT  DevNo, '+@strMaxHarmStamp+',Convert(varchar,(select top 1 [MaxHarmStamp] from MonthStats whereDevNo='+@devNo+' and MaxHarm=(select max(MaxHarm) from MonthStats whereDevNo='+@devNo+')),112) 合计 FROM MonthStats whereDevNo='+@devNo+' group by DevNo
  union all
 SELECT  DevNo, '+@strMinHarmStamp+',Convert(varchar,(select top 1 [MinHarmStamp] from MonthStats whereDevNo='+@devNo+' and MinHarm=(select min(MinHarm) from MonthStats whereDevNo='+@devNo+')),112) 合计 FROM MonthStats whereDevNo='+@devNo+' group by DevNo
 union all
 SELECT  DevNo,' +@strSafeTimeHarm+',Convert(varchar,sum(SafeTimeHarm)) 合计 FROM MonthStats whereDevNo='+@devNo+' group by DevNo
   union all
 SELECT  DevNo,' +@strSafeRateHarm+',Convert(varchar,sum(SafeRateHarm)) 合计 FROM MonthStats whereDevNo='+@devNo+' group by DevNo
   union all
 SELECT  DevNo,' +@strWarmTimeHarm+',Convert(varchar,sum(WarmTimeHarm)) 合计 FROM MonthStats whereDevNo='+@devNo+' group by DevNo
   union all
 SELECT  DevNo,' +@strWarmRateHarm+',Convert(varchar,sum(WarmRateHarm)) 合计 FROM MonthStats whereDevNo='+@devNo+' group by DevNo
 ')

 

执行语句

EXEC PP 1,2010

 

效果:

  

图:

 

这里要声明一下,我也问了csdn里面的高手,告诉我用union all去衔接表的,我开始总输出一行很悲剧。

主要是平时在学习中,sql函数不太了解。

后面通过写一个复杂一点的过程,了解什么是聚合函数,什么是非聚合函数?。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 淘宝充值流量没到账怎么办 微信手机充错了怎么办 支付宝充话费没到账怎么办 裤子摔了一个洞怎么办 顾客反应衣服质量不好怎么办 淘宝买的衣服味道很大怎么办 三国杀账号忘了怎么办 宽带连接被删了 怎么办 手机被偷了qq怎么办 手机丢了微信怎么办啊 手机店把手机修坏了怎么办 在手机店买到山寨机手机怎么办 有人在qq群上骂我怎么办 qq群一直有人骚扰怎么办 苹果手机QQ图标不在桌面上怎么办 苹果手机长按不能删除怎么办 qq发的图片过期怎么办 九黎八卦在仓库怎么办 飞猪f2领了万豪银卡没住怎么办 机械键盘摁键冲突怎么办 玩游戏键盘没反应怎么办 玩枪战游戏头晕恶心怎么办 手机看视频不能横屏怎么办 苹果手机安全码忘记了怎么办 信用卡安全码忘记了怎么办 联想电脑管家阻止我安装软件怎么办 word恢复后打开乱码怎么办 苹果手机局域网也登陆不了怎么办 剑三账号冻结7天怎么办 荒野行动无缘无故被限制时间怎么办 电脑打游戏闪屏怎么办 微信下载出现数据包出错怎么办 安卓平板闪退怎么办 剑侠世界2出了1怎么办 苹果手机有木马病毒删除不了怎么办 苹果手机病毒了怎么办【解决方法】 苹果手机点击病毒链接怎么办 苹果手机有病毒啦怎么办 苹果7p反复重启怎么办 苹果手机屏幕触屏不灵怎么办 苹果手机屏翘起来了怎么办