sql行转列 交叉 合并

aplesen 2010-04-23 05:46:13
数据库表如下
时间 员工 班别
2010-04-23 王梅 早班
2010-04-25 周晓丽 晚班
2010-04-25 刘燕 晚班
2010-04-25 王梅 晚班
2010-04-23 明月 早班
2010-04-24 陈红云 早班
2010-04-24 孙红梅 早班
2010-04-24 刘燕 早班
2010-04-23 孙红梅 早班
2010-04-23 陈红云 早班
我想显示成这样的请问怎么做?
时间 早班 中班 晚班
2010-04-23 王梅,明月,孙红梅,陈红云
2010-04-24 陈红云,孙红梅,刘燕
2010-04-25 周晓丽,刘燕,王梅


其中 日期,班别,人数 都是不确定的 请达人帮忙解决。
...全文
210 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
aplesen 2010-04-26
  • 打赏
  • 举报
回复
昨天网络有问题,不好意思,没来及回复
aplesen 2010-04-26
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 happycell188 的回复:]
SQL code
--修改一下:
declare @sql varchar(max),@i int,@name char(100)
declare @tb table (id int identity(1,1),_name char(100))
insert into @tb select distinct 班别 from tb
select @i=1
while(@i<=(selec……
[/Quote]

恩,是可以实现,还请帮个忙,呵呵 新手 不好意思
declare @sql varchar(max),@i int,@name char(100)
declare @tb table (id int identity(1,1),_name char(100))
insert into @tb select distinct cName from View_Scheduling
select @i=1
while(@i<=(select count(*) from @tb))
begin
select top 1 @name=_name from @tb where id not in (select top (@i-1) id from @tb)
set @sql=isnull(@sql+','+@name+'=case cName when '''+@name+''' then temp end',@name+'=case cName when '''+@name+''' then temp end')
set @i=@i+1
end
set @sql='select sDate,'+@sql+' from (
select sDate,cName,
temp=stuff((select '',''+rtrim(eName) from View_Scheduling where sDate=t.sDate for xml path('''')),1,1,'''') from View_Scheduling t
group by sDate,cName )t'
exec(@sql)
这是我修改后的,基本就是换个表名和列名
然后我还有个条件就是
就是得到上面的那些数据还有条件就是
select * from View_Scheduling where sOutal='801'
其中那个 801 是变量 也就是它会变,所以麻烦你再看看,还有我是在页面里面返回datatable的 这样复制进去会不会不行啊。
新手见谅!
喜-喜 2010-04-24
  • 打赏
  • 举报
回复
--修改一下:
declare @sql varchar(max),@i int,@name char(100)
declare @tb table (id int identity(1,1),_name char(100))
insert into @tb select distinct 班别 from tb
select @i=1
while(@i<=(select count(*) from @tb))
begin
select top 1 @name=_name from @tb where id not in (select top (@i-1) id from @tb)
set @sql=isnull(@sql+','+@name+'=case 班别 when '''+@name+''' then temp end',@name+'=case 班别 when '''+@name+''' then temp end')
set @i=@i+1
end
set @sql='select 时间,'+@sql+' from (
select 时间,班别,
temp=stuff((select '',''+rtrim(员工) from tb where 时间=t.时间 for xml path('''')),1,1,'''') from tb t
group by 时间,班别 )t'
exec(@sql)
喜-喜 2010-04-24
  • 打赏
  • 举报
回复
'这次不需要班别的具体信息了,你看下能实现不...'

--------------------SQL Server数据格式化工具-------------------
---------------------------------------------------------------
-- DESIGNER :happycell188(喜喜)
-- QQ :584738179
-- Development Tool :Microsoft Visual C++ 6.0 C Language
-- FUNCTION :CONVERT DATA TO T-SQL
---------------------------------------------------------------
-- Microsoft SQL Server 2005
-- Developer Edition on Microsoft Windows XP [版本 5.1.2600]
---------------------------------------------------------------
---------------------------------------------------------------

use test
go
if object_id('test.dbo.tb') is not null drop table tb
-- 创建数据表
create table tb
(
时间 char(11),
员工 char(7),
班别 char(5)
)
go
--插入测试数据
insert into tb select '2010-04-23','王梅','早班'
union all select '2010-04-25','周晓丽','晚班'
union all select '2010-04-25','刘燕','晚班'
union all select '2010-04-25','王梅','晚班'
union all select '2010-04-23','明月','早班'
union all select '2010-04-24','陈红云','早班'
union all select '2010-04-24','孙红梅','早班'
union all select '2010-04-24','刘燕','早班'
union all select '2010-04-23','孙红梅','早班'
union all select '2010-04-23','陈红云','早班'
go
--代码实现

declare @sql varchar(1000),@i int,@name char(4)
declare @tb table (id int identity(1,1),_name char(4))
insert into @tb select distinct 班别 from tb
select @i=1
while(@i<=(select count(*) from @tb))
begin
select top 1 @name=_name from @tb where id not in (select top (@i-1) id from @tb)
set @sql=isnull(@sql+','+@name+'=case 班别 when '''+@name+''' then temp end',@name+'=case 班别 when '''+@name+''' then temp end')
set @i=@i+1
end
set @sql='select 时间,'+@sql+' from (
select 时间,班别,
temp=stuff((select '',''+rtrim(员工) from tb where 时间=t.时间 for xml path('''')),1,1,'''') from tb t
group by 时间,班别 )t'
exec(@sql)

--select 时间,早班=case 班别 when '早班' then temp end,
--中班=case 班别 when '中班' then temp end,
--晚班=case 班别 when '晚班' then temp end
--from (
--select 时间,班别,
--temp=stuff((select ','+rtrim(员工) from tb where 时间=t.时间 for xml path('')),1,1,'') from tb t
--group by 时间,班别 )t

/*测试结果

时间 晚班 中班
--------------------------------------------------------------
2010-04-23 NULL 王梅,明月,孙红梅,陈红云
2010-04-24 NULL 陈红云,孙红梅,刘燕
2010-04-25 周晓丽,刘燕,王梅 NULL

(3 行受影响)
*/

aplesen 2010-04-24
  • 打赏
  • 举报
回复
这样吧 我就让他 只有早中晚班吧 我快崩溃了 都星期六还在想着项目的事 哎
htl258_Tony 2010-04-24
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 aplesen 的回复:]
引用 9 楼 htl258 的回复:
那就尝试做一个固定班次表,用这张表来LEFT JOIN数据不就可以了吗


这个系统比较特殊 有n家分支机构 他们的班是不一样的 所以很难固定
[/Quote]

如果是这种情况,是可以考虑做一张固定班次表,再结合动态SQL就能实现了。
aplesen 2010-04-24
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 happycell188 的回复:]
引用 6 楼 aplesen 的回复:
数据库表如下
时间(sDate) 员工(eName) 班别(cName)
2010-04-23 王梅 早班
2010-04-25 周晓丽 晚班
2010-04-25 刘燕 晚班
2010-04-25 王梅 晚班
2010-04-23 明月 早班
2010-04-24 陈红云 早班
2010-04-24 孙红梅 早班
2010-04-24 ……
[/Quote]

我打了空格的,贴出来就没了,不知道为什么,意思就是 显示成 2楼 那样的结果,但是 班别 不只是早中晚,是不确定的 可能有30多个,而且不确定 有几个
htl258_Tony 2010-04-24
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 aplesen 的回复:]
有些复杂,速度上不是很好,有没有最佳的解决方案啊 要是资料不详细 你们说我可以再加上
[/Quote]
速度上是优化的问题了,语句用楼上几位静态的写法应该无可挑剔了。
dawugui 2010-04-24
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 aplesen 的回复:]
引用 9 楼 htl258 的回复:
那就尝试做一个固定班次表,用这张表来LEFT JOIN数据不就可以了吗


这个系统比较特殊 有n家分支机构 他们的班是不一样的 所以很难固定
[/Quote]
那就尝试做一个固定班次表,分别存储N家分支机构不同的班次.
aplesen 2010-04-24
  • 打赏
  • 举报
回复
有些复杂,速度上不是很好,有没有最佳的解决方案啊 要是资料不详细 你们说我可以再加上
喜-喜 2010-04-24
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 aplesen 的回复:]
数据库表如下
时间(sDate) 员工(eName) 班别(cName)
2010-04-23 王梅 早班
2010-04-25 周晓丽 晚班
2010-04-25 刘燕 晚班
2010-04-25 王梅 晚班
2010-04-23 明月 早班
2010-04-24 陈红云 早班
2010-04-24 孙红梅 早班
2010-04-24 刘燕 早班
2010-04-23 孙红梅……
[/Quote]

能再说明白点儿不?

你的结果数据有四个字段,但下面只有两列数据!是二楼的显示结果吗?

“这个排班是时刻变化的 不能那样写死啊”,不呢个那样写死是什么意思?
htl258_Tony 2010-04-24
  • 打赏
  • 举报
回复
看错了,用静态SQL类似楼上几位那样编好是可以做到。
dawugui 2010-04-24
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 aplesen 的回复:]
引用 7 楼 dawugui 的回复:
你的数据也没有提供有中班的内容,即使用动态SQL也实现不了你的需求.
还不如用4的静态SQL.


是啊 他可能有的班没人上班,我也没办法啊
[/Quote]
那不就得用静态SQL了?或者用楼上说的把内容装到一个表里面去.
aplesen 2010-04-24
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 htl258 的回复:]
那就尝试做一个固定班次表,用这张表来LEFT JOIN数据不就可以了吗
[/Quote]

这个系统比较特殊 有n家分支机构 他们的班是不一样的 所以很难固定
htl258_Tony 2010-04-24
  • 打赏
  • 举报
回复
那就尝试做一个固定班次表,用这张表来LEFT JOIN数据不就可以了吗
aplesen 2010-04-24
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 dawugui 的回复:]
你的数据也没有提供有中班的内容,即使用动态SQL也实现不了你的需求.
还不如用4的静态SQL.
[/Quote]

是啊 他可能有的班没人上班,我也没办法啊
dawugui 2010-04-24
  • 打赏
  • 举报
回复
你的数据也没有提供有中班的内容,即使用动态SQL也实现不了你的需求.
还不如用4的静态SQL.
aplesen 2010-04-24
  • 打赏
  • 举报
回复
数据库表如下
时间(sDate) 员工(eName) 班别(cName)
2010-04-23 王梅 早班
2010-04-25 周晓丽 晚班
2010-04-25 刘燕 晚班
2010-04-25 王梅 晚班
2010-04-23 明月 早班
2010-04-24 陈红云 早班
2010-04-24 孙红梅 早班
2010-04-24 刘燕 早班
2010-04-23 孙红梅 早班
2010-04-23 陈红云 早班
我想显示成这样的请问怎么做?
时间 早班 中班 晚班
2010-04-23 王梅,明月,孙红梅,陈红云
2010-04-24 陈红云,孙红梅,刘燕
2010-04-25 周晓丽,刘燕,王梅


我把数据库字段也加上了,麻烦再看看


其中 日期,班别,人数 都是不确定的 请达人帮忙解决。
aplesen 2010-04-24
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 josy 的回复:]
SQL code
---测试数据---
if object_id('[tb]') is not null drop table [tb]
go
create table [tb]([时间] datetime,[员工] varchar(6),[班别] varchar(4))
insert [tb]
select '2010-04-23','王梅','早班' union all
sele……
[/Quote]

这个,这个。。。
似乎你们没明白我意思啊,
这个排班是时刻变化的 不能那样写死啊
dawugui 2010-04-24
  • 打赏
  • 举报
回复
--sql 2000用函数实现.
create table [tb]([时间] datetime,[员工] varchar(6),[班别] varchar(4))
insert [tb]
select '2010-04-23','王梅','早班' union all
select '2010-04-25','周晓丽','晚班' union all
select '2010-04-25','刘燕','晚班' union all
select '2010-04-25','王梅','晚班' union all
select '2010-04-23','明月','早班' union all
select '2010-04-24','陈红云','早班' union all
select '2010-04-24','孙红梅','早班' union all
select '2010-04-24','刘燕','早班' union all
select '2010-04-23','孙红梅','早班' union all
select '2010-04-23','陈红云','早班'
go

create function dbo.f_str(@时间 datetime , @班别 varchar(4)) returns varchar(100)
as
begin
declare @str varchar(1000)
set @str = ''
select @str = @str + ',' + cast(员工 as varchar) from tb where 时间 = @时间 and 班别 = @班别
set @str = right(@str , len(@str) - 1)
return @str
end
go

--调用函数+行列转换
select convert(varchar(10),时间,120) 时间,
max(case 班别 when '早班' then 员工 else '' end) [早班],
max(case 班别 when '中班' then 员工 else '' end) [中班],
max(case 班别 when '晚班' then 员工 else '' end) [晚班]
from
(
select 时间 , 班别 , 员工 = dbo.f_str(时间 , 班别) from tb group by 时间 , 班别
) t
group by convert(varchar(10),时间,120)

drop function dbo.f_str
drop table tb

/*
时间 早班 中班 晚班
---------- ---------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------
2010-04-23 王梅,明月,孙红梅,陈红云
2010-04-24 陈红云,孙红梅,刘燕
2010-04-25 周晓丽,刘燕,王梅

(所影响的行数为 3 行)

*/
加载更多回复(3)

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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