SQL按字段内容分组的存储过程

hansen_chen 2010-06-12 10:51:47
有个表如下,Test资料如下
if object_id('[tb]') is not null drop table [tb]
go
create table [tb]([姓名] varchar(1),[部门] varchar(4),[学历] varchar(4),[出生年月] datetime)
insert [tb]
select 'A','后勤','高中','1986-1-1' union all
select 'B','后勤','初中','1984-3-7' union all
select 'C','管理','本科','1987-2-1' union all
select 'D','操作','专科','1976-2-1' union all
select 'E','操作','专科','1943-2-1'
要分组统计学历人数如下:

部门 本科 初中 高中 专科
---- ---------- ----------- ----------- -----------
管理 1 0 0 0
后勤 0 1 1 0
操作 0 0 0 1
操作 0 0 0 1

我在查询分析器用以下语句实现了
--------------开始查询--------------------------
declare @sql varchar(8000)
set @sql = 'select 部门'
select @sql = @sql + ' , sum(case 学历 when ''' + 学历 + ''' then 1 else 0 end) [' + 学历 + ']'
from (select distinct 学历 from tb) as a
set @sql = @sql + ' from tb group by 部门'
exec(@sql)

我想写个过程,对传进的字段按字段内容进行分组(如上列)过程如下

CREATE PROCEDURE [dbo].[GetGroupByCol]
@colm(nvchar(100))
AS
declare @sql varchar(8000)
set @sql='select 部门'
select @sql =@sql+ ', sum(case @colm when ''' + @colm + ''' then 1 else 0 end) [' + @colm + ']' from (select distinct @colm from v_hr_person) as a
set @sql = @sql + ' from v_hr_person group by 部门'
exec(@sql)
GO
老是提示没有为A指定列……,我要如何修改?上面的语句能用一句SQL实现或有其他更简单的方法
...全文
1174 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
查理001 2013-01-06
  • 打赏
  • 举报
回复
说到底就是个多层引号嵌套的问题
qdrccp 2011-02-11
  • 打赏
  • 举报
回复
再次见证了一位高手。。
lcw321321 2010-06-12
  • 打赏
  • 举报
回复
用排名函数 加GROUP BY 很容易就实现了
永生天地 2010-06-12
  • 打赏
  • 举报
回复

if object_id('[tb]') is not null drop table [tb]
go
create table [tb]([姓名] varchar(1),[部门] varchar(4),[学历] varchar(4),[出生年月] datetime)
insert [tb]
select 'A','后勤','高中','1986-1-1' union all
select 'B','后勤','初中','1984-3-7' union all
select 'C','管理','本科','1987-2-1' union all
select 'D','操作','专科','1976-2-1' union all
select 'E','操作','专科','1943-2-1'
go
if object_id('GetGroupByCol') is not null drop proc GetGroupByCol
go
create PROCEDURE [dbo].[GetGroupByCol]
@colm nvarchar(100)
AS
declare @sql varchar(4000)
set @sql='
declare @sql varchar(8000)
set @sql=''select 部门''
select @sql =@sql+ '', sum(case ltrim('+@colm+') when ''''''+ltrim(' + @colm + ')+'''''' then 1 else 0 end) [''+ltrim(' + @colm + ')+'']'' from (select distinct '+@colm+' from tb) as a
set @sql = @sql + '' from tb group by 部门''
exec(@sql)'

exec(@sql)
GO

exec GetGroupByCol N'学历'
exec GetGroupByCol N'出生年月'
exec GetGroupByCol N'姓名'

/*

(所影响的行数为 5 行)

部门 本科 初中 高中 专科
---- ----------- ----------- ----------- -----------
操作 0 0 0 2
管理 1 0 0 0
后勤 0 1 1 0

(所影响的行数为 3 行)

部门 02 1 1943 12:00AM 02 1 1976 12:00AM 03 7 1984 12:00AM 01 1 1986 12:00AM 02 1 1987 12:00AM
---- ------------------ ------------------ ------------------ ------------------ ------------------
操作 1 1 0 0 0
管理 0 0 0 0 1
后勤 0 0 1 1 0

(所影响的行数为 3 行)

部门 A B C D E
---- ----------- ----------- ----------- ----------- -----------
操作 0 0 0 1 1
管理 0 0 1 0 0
后勤 1 1 0 0 0

(所影响的行数为 3 行)


*/
hansen_chen 2010-06-12
  • 打赏
  • 举报
回复
再次感谢xys_777!
今天从你这学到很多,为了完善这个存储过程,如果把NULL把它统计成‘未输入’栏位,不知怎么改?再麻烦帮忙!
永生天地 2010-06-12
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 hansen_chen 的回复:]
谢谢xys_777,基本解决了!再请教下字段值中如果有NULL是不会返回结果,要如何修改?
[/Quote]
加条件
if object_id('GetGroupByCol') is not null drop proc GetGroupByCol
go
create PROCEDURE [dbo].[GetGroupByCol]
@colm nvarchar(100)
AS
declare @sql varchar(4000)
set @sql='
declare @sql varchar(8000)
set @sql=''select 部门''
select @sql =@sql+ '', sum(case ltrim('+@colm+') when ''''''+ltrim(' + @colm + ')+'''''' then 1 else 0 end) [''+ltrim(' + @colm + ')+'']'' from (select distinct '+@colm+' from tb where '+@colm+' is not null) as a
set @sql = @sql + '' from tb group by 部门''
exec(@sql)'

exec(@sql)
GO
hansen_chen 2010-06-12
  • 打赏
  • 举报
回复
谢谢xys_777,基本解决了!再请教下字段值中如果有NULL是不会返回结果,要如何修改?

34,590

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧