sql行列转换,字符串相加

 
  

if object_id('tb')is not null
drop table tb;

CREATE TABLE [dbo].[tb](
    [name] [varchar](50) NULL,
    [class] [varchar](50) NULL,
    [score] [int] NULL
) ON [PRIMARY]
insert into tb values('张三','语文',74)
insert into tb values('张三','数学',83)
insert into tb values('张三','物理',93)
insert into tb values('李四','语文',74)
insert into tb values('李四','数学',84)
insert into tb values('李四','物理',94)
 

使用case ..when..then..else..end

1.静态的

select name ,MAX(case class when N'语文' then score else 0 end) 语文,
MAX(case class when N'数学' then score else 0 end) 数学,
MAX(case class when N'物理' then score else 0 end) 物理,
sum(score) 总分,
cast(avg(score*1.0)as decimal(18,2))平均分
from tb group by name

动态的

declare @sql varchar(8000)
set @sql = 'select name '
select @sql = @sql + ' , max(case class when ''' + class + ''' then score else 0 end) [' + class + ']'//循环调用
from (select distinct class from tb) as a
set @sql = @sql + ' from tb group by name'
print(@sql);
exec(@sql)

使用pivot

静态

select m.*,n.总分,n.平均分
from
(select * from tb pivot(max(score)for class in(语文,数学,物理))a)m,
(select name,sum(score)总分,cast(avg(score*1.0)as decimal(18,2))平均分
from tb
group by name)n
where m.name=n.name

动态

declare @sql varchar(8000)
set @sql=''  --初始化变量@sql
select @sql=@sql+','+class from tb group by class--变量多值赋值
--同select @sql = @sql + ','+课程from (select distinct课程from tb)a
set @sql=stuff(@sql,1,1,'')--去掉首个','
set @sql='select m.* , n.总分,n.平均分 from
(select * from (select * from tb) a pivot (max(score) for class in ('+@sql+')) b) m ,
(select name,sum(score)总分, cast(avg(score*1.0) as decimal(18,2))平均分 from tb group by name) n
where m.name= n.name'
print(@sql);
exec(@sql)

 stuff用法:

以下示例在第一个字符串 abcdef 中删除从第 2 个位置(字符 b)开始的三个字符,然后在删除的起始位置插入第二个字符串,从而创建并返回一个字符串

SELECT STUFF('abcdef', 2, 3, 'ijklmn'),有点想js中的splice

http://www.cnblogs.com/zhangzt/archive/2010/07/29/1787825.html

http://bbs.csdn.net/topics/330058353

http://www.cnblogs.com/doubleliang/archive/2011/07/06/2098775.html

例子:

有个表Kqjl_Info

有三个字段,sfzh(身份证号,进出时间,进出状态(1进,0出))

计算一个员工是否上班,就看他的进出状态是否有1,0,就是先进,然后再出

最后想输出

就是一个月内这个人上了那几天班

具体sql:

 with ta as (select sfzh,kqsj,jczt from Kqjl_Info)
select sfzh,
max(case dd when 1 then jczt else 0 end) d1,
max(case dd when 2 then jczt else 0 end) d2,
max(case dd when 3 then jczt else 0 end) d3,
max(case dd when 4 then jczt else 0 end) d4,
max(case dd when 5 then jczt else 0 end) d5,
max(case dd when 6 then jczt else 0 end) d6,
max(case dd when 7 then jczt else 0 end) d7,
max(case dd when 8 then jczt else 0 end) d8,
max(case dd when 9 then jczt else 0 end) d9,
max(case dd when 10 then jczt else 0 end) d10,
max(case dd when 11 then jczt else 0 end) d11,
max(case dd when 12 then jczt else 0 end) d12,
max(case dd when 13 then jczt else 0 end) d13,
max(case dd when 14 then jczt else 0 end) d14,
max(case dd when 15 then jczt else 0 end) d15,
max(case dd when 16 then jczt else 0 end) d16,
max(case dd when 17 then jczt else 0 end) d17,
max(case dd when 18 then jczt else 0 end) d18,
max(case dd when 19 then jczt else 0 end) d19,
max(case dd when 20 then jczt else 0 end) d20,
max(case dd when 21 then jczt else 0 end) d21,
max(case dd when 22 then jczt else 0 end) d22,
max(case dd when 23 then jczt else 0 end) d23,
max(case dd when 24 then jczt else 0 end) d24,
max(case dd when 25 then jczt else 0 end) d25,
max(case dd when 26 then jczt else 0 end) d26,
max(case dd when 27 then jczt else 0 end) d27,
max(case dd when 28 then jczt else 0 end) d28,
max(case dd when 29 then jczt else 0 end) d29,
max(case dd when 30 then jczt else 0 end) d30,
max(case dd when 31 then jczt else 0 end) d31,
sum(jczt) totalCount
from (select sfzh,dd,jczt=1 from (select sfzh,day(kqsj) as dd,
(select cast(jczt as varchar)+',' from ta where sfzh=a.sfzh and day(kqsj)=day(a.kqsj) 
order by kqsj  for xml path('') ) as zt from ta a group by sfzh,day(kqsj)) as tb 
where tb.zt like '%1,0%') as tc group by sfzh;

分析:

 with ta as (select sfzh,kqsj,jczt from Kqjl_Info)
 select sfzh,day(kqsj),(select cast(jczt as varchar)+',' from ta where sfzh=a.sfzh and day(kqsj)=day(a.kqsj) order by kqsj  for xml path('') ) as zt from ta a group by sfzh,day(kqsj) 

再选择有1,0的员工,再行列转换

 

 use EntranceVista;
  with ta as ( select a.sfzh,a.kqsj,a.jczt,b.xm,gz=b.gz1,a.qybmm  from Kqjl_Info a join Ry_Info b on a.sfzh=b.sfzh  where  1=1  and a.kqsj<='2015-08-25 23:59:59' and a.kqsj>='2015-07-26 00:00:00' )
 select xh=ROW_NUMBER()over (order  by qybmm,xm ),tt.*,b.xm,b.gz,b.qybmm from ta b join(select aa='',bb='',cc='',dd='',ee='',ff='',gg='',hh='',ii='',jj='',sfzh,totalCount=COUNT(1) from ( select sfzh,day(kqsj) as dd,(select cast(jczt as varchar)+',' from ta where sfzh=a.sfzh and day(kqsj)=day(a.kqsj) order by kqsj  for xml path('') ) as zt from ta a group by sfzh,day(kqsj)) as td where zt like '%1,0%' group by sfzh ) tt  on tt.sfzh=b.sfzh order by b.qybmm,b.xm



select xh=ROW_NUMBER()over (order  by qybmm,xm ),tt.*,b.xm,b.gz,b.qybmm from  ta b join( select sfzh, 
 max(case dd when 1 then jczt else 0 end) d1,
 max(case dd when 2 then jczt else 0 end) d2,
 max(case dd when 3 then jczt else 0 end) d3,
 max(case dd when 4 then jczt else 0 end) d4,max(case dd when 5 then jczt else 0 end) d5,max(case dd when 6 then jczt else 0 end) d6,max(case dd when 7 then jczt else 0 end) d7,max(case dd when 8 then jczt else 0 end) d8,max(case dd when 9 then jczt else 0 end) d9,max(case dd when 10 then jczt else 0 end) d10,max(case dd when 11 then jczt else 0 end) d11,max(case dd when 12 then jczt else 0 end) d12,max(case dd when 13 then jczt else 0 end) d13,max(case dd when 14 then jczt else 0 end) d14,max(case dd when 15 then jczt else 0 end) d15,max(case dd when 16 then jczt else 0 end) d16,max(case dd when 17 then jczt else 0 end) d17,max(case dd when 18 then jczt else 0 end) d18,max(case dd when 19 then jczt else 0 end) d19,max(case dd when 20 then jczt else 0 end) d20,max(case dd when 21 then jczt else 0 end) d21,max(case dd when 22 then jczt else 0 end) d22,max(case dd when 23 then jczt else 0 end) d23,max(case dd when 24 then jczt else 0 end) d24,max(case dd when 25 then jczt else 0 end) d25,max(case dd when 26 then jczt else 0 end) d26,max(case dd when 27 then jczt else 0 end) d27,max(case dd when 28 then jczt else 0 end) d28,max(case dd when 29 then jczt else 0 end) d29,max(case dd when 30 then jczt else 0 end) d30,
 max(case dd when 31 then jczt else 0 end) d31,
 sum(jczt) totalCount  from (
 select sfzh,dd,jczt=1 from (
 select sfzh,day(kqsj) as dd, (
 select cast(jczt as varchar)+',' from ta where sfzh=a.sfzh and day(kqsj)=day(a.kqsj)  order by kqsj  for xml path('') ) as zt 
 from ta a group by sfzh,day(kqsj)) as tb 
  where tb.zt like '%1,0%') as tc group by sfzh ) tt   on tt.sfzh=b.sfzh order by b.qybmm,b.xm

 

  DBCC DROPCLEANBUFFERS
  --清除buffer pool里的所有缓存数据
 DBCC freeproccache
 GO
  
  --清除buffer pool里的所有缓存的执行计划
  SET STATISTICS TIME ON
  GO
  USE [EntranceVista]
 GO
  with ta as (select sfzh,kqsj,jczt from Kqjl_Info)
 select sfzh,day(kqsj),(select cast(jczt as varchar)+',' from ta where sfzh=a.sfzh and day(kqsj)=day(a.kqsj) order by kqsj  for xml path('') ) as zt from ta a group by sfzh,day(kqsj) 

 GO
 SET STATISTICS TIME OFF
 GO

报告:

DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。
DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。
SQL Server 分析和编译时间: 
   CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。

 SQL Server 执行时间:
   CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
SQL Server 分析和编译时间: 
   CPU 时间 = 0 毫秒,占用时间 = 39 毫秒。

(47390 行受影响)

 SQL Server 执行时间:
   CPU 时间 = 15802 毫秒,占用时间 = 18523 毫秒。

 http://www.cnblogs.com/doubleliang/archive/2011/07/06/2098775.html

 

要实现SQL中的字符串相加,可以使用GROUP_CONCAT函数或者使用XML PATH方法。其中,GROUP_CONCAT函数用于将多个字符串连接在一起,而XML PATH方法则用于将多个字符串连接为一个新的字符串。 在第一个引用中的SQL语句中,使用了GROUP_CONCAT函数来实现字符串相加。例如,可以使用以下语句实现字符串相加: SELECT a.*, GROUP_CONCAT(p.name) FROM area a LEFT JOIN area_product ap ON a.id = ap.area_id LEFT JOIN product p ON p.id = ap.product_id GROUP BY a.id 在第二个引用中的SQL语句中,使用了XML PATH方法来实现字符串相加。例如,可以使用以下语句实现字符串相加: SELECT BeginCity, EndCity, FanDian, [CangWei] = STUFF((SELECT '/' + [CangWei] FROM Test1 t WHERE t.BeginCity = Test1.BeginCity AND t.EndCity = Test1.EndCity AND t.FanDian = Test1.FanDian FOR XML PATH('')), 1, 1, '') FROM Test1 GROUP BY BeginCity, EndCity, FanDian 以上就是两种在SQL中实现字符串相加的方法,分别是使用GROUP_CONCAT函数和使用XML PATH方法。<span class="em">1</span><span class="em">2</span> #### 引用[.reference_title] - *1* [如何在group by 中取得字符串相加的值](https://blog.csdn.net/qq_43294932/article/details/127637710)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [SQL查询语句 group by后, 字符串合并](https://blog.csdn.net/weixin_34404393/article/details/85690458)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值