问大家一个关于行转列的问题[有点小复杂]

倒霉熊 2011-08-09 02:35:17


图中为一个视图查询出来的结果。
想要的效果是:根据 SO_processID 分组,如图中SO_processID分别为130和141,那么我想要查询出来的记录只有两条,
后面是根据SO_SI_StepName转换成列名描述起来比较复杂。

这是一个工作流,处理的步骤,想要导出报表,每一个SO_processID导出为一条记录,SO_SI_StepName拆分成5个列,分别为

SO_SI_StepName+获取时间(列名) = SO_SI_GETTIME
SO_SI_StepName+完成时间(列名) = SO_SI_COMPTIME
SO_SI_StepName+处理人(列名) = SO_SI_OPTIONTOR
SO_SI_StepName+备注(列名) = SO_SI_NOTES
这些,都比较好处理主要这之后又需要两个不存在的列
SO_SI_StepName+限制周期(列名) = 每个SO_SI_StepName的限制周期都不同
SO_SI_StepName+延迟周期(列名) = 完成时间 - 获取时间 - 限制周期

这下可难倒我啦..因为这些SO_SI_StepName在每个SO_processID里面也都不唯一,因为工作流有可能退回重新处理嘛...


我知道描述的不清楚下面是我看其中一个小例子(效果):

---列名 其中的LOB就是表记录中的数据
SO_processID LOB获取时间  LOB完成时间 LOB处理人  LOB备注 LOB限制周期 LOB完成周期 LOB确认获取时间  LOB确认完成时间 LOB确认处理人  LOB确认备注 LOB确认限制周期 LOB确认完成周期 
...全文
122 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
快溜 2011-08-09
  • 打赏
  • 举报
回复
create table tb1 (sname varchar(10),classname varchar(10),oldcores int,nowcores int,note varchar(20))
go
insert into tb1 values('张三','语文',74,90,'及格')
insert into tb1 values('张三','数学',83,20,'更差')
insert into tb1 values('张三','物理',93,100,'不错')
insert into tb1 values('李四','语文',74,74,'随便')
insert into tb1 values('李四','数学',84,90,'还行')
insert into tb1 values('李四','物理',94,40,'差劲')
go

select sname,
语文上次分数=max(case when classname='语文' then oldcores end),
语文最新分数=max(case when classname='语文' then nowcores end),
语文老师评语=max(case when classname='语文' then note end),
语文限制分数=5,
语文超出分数=MAX(case when classname='语文' then nowcores-oldcores-5 end),
数学上次分数=max(case when classname='数学' then oldcores end),
数学最新分数=max(case when classname='数学' then nowcores end),
数学老师评语=max(case when classname='数学' then note end),
数学限制分数=3,
数学超出分数=MAX(case when classname='数学' then nowcores-oldcores-3 end),
物理上次分数=max(case when classname='物理' then oldcores end),
物理最新分数=max(case when classname='物理' then nowcores end),
物理老师评语=max(case when classname='物理' then note end),
物理限制分数=4,
物理超出分数=MAX(case when classname='物理' then nowcores-oldcores-4 end)
from tb1 group by sname


/*
sname 语文上次分数 语文最新分数 语文老师评语 语文限制分数 语文超出分数 数学上次分数 数学最新分数 数学老师评语 数学限制分数 数学超出分数 物理上次分数 物理最新分数 物理老师评语 物理限制分数 物理超出分数
---------- ----------- ----------- -------------------- ----------- ----------- ----------- ----------- -------------------- ----------- ----------- ----------- ----------- -------------------- ----------- -----------
李四 74 74 随便 5 -5 84 90 还行 3 3 94 40 差劲 4 -58
张三 74 90 及格 5 11 83 20 更差 3 -66 93 100 不错 4 3
警告: 聚合或其他 SET 操作消除了 Null 值。

(2 行受影响)



如此疲惫 2011-08-09
  • 打赏
  • 举报
回复

楼主是18楼的意思?
AcHerat 2011-08-09
  • 打赏
  • 举报
回复

create table tb1 (sname varchar(10),classname varchar(10),oldcores int,nowcores int,note varchar(20))
go
insert into tb1 values('张三','语文',74,90,'及格')
insert into tb1 values('张三','数学',83,20,'更差')
insert into tb1 values('张三','物理',93,100,'不错')
insert into tb1 values('李四','语文',74,74,'随便')
insert into tb1 values('李四','数学',84,90,'还行')
insert into tb1 values('李四','物理',94,40,'差劲')
go

create table tb2 (classname varchar(10),score int)
insert into tb2
select '语文',5 union all
select '数学',6 union all
select '物理',8
go

declare @sql varchar(8000)
set @sql = 'select a.sname'
select @sql = @sql+',max(case a.classname when '''+classname+''' then a.oldcores else null end) ['+classname+'上次分数]'
+',max(case a.classname when '''+classname+''' then a.nowcores else null end) ['+classname+'最新分数]'
+',max(case a.classname when '''+classname+''' then a.note else null end) ['+classname+'老师评语]'
+',max(case a.classname when '''+classname+''' then b.score else null end) ['+classname+'限制分数]'
+',max(case a.classname when '''+classname+''' then a.nowcores-a.oldcores-b.score else null end) ['+classname+'超出分数]'
from tb1
group by classname
select @sql = @sql + ' from tb1 a join tb2 b on a.classname = b.classname group by a.sname'
exec(@sql)

drop table tb1,tb2

/************

sname 数学上次分数 数学最新分数 数学老师评语 数学限制分数 数学超出分数 物理上次分数 物理最新分数 物理老师评语 物理限制分数 物理超出分数 语文上次分数 语文最新分数 语文老师评语 语文限制分数 语文超出分数
---------- ----------- ----------- -------------------- ----------- ----------- ----------- ----------- -------------------- ----------- ----------- ----------- ----------- -------------------- ----------- -----------
李四 84 90 还行 6 0 94 40 差劲 8 -62 74 74 随便 5 -5
张三 83 20 更差 6 -69 93 100 不错 8 -1 74 90 及格 5 11
警告: 聚合或其他 SET 操作消除了空值。

(2 行受影响)


类似了。
倒霉熊 2011-08-09
  • 打赏
  • 举报
回复
不知道这样大家能明白不...嗯,就是给学生的成绩按照姓名变成一列数据

限制分数,每个学生都是一样的,不过每个课程不一样,是固定死的,比如语文固定 5分 数学固定 3分 物理固定4分
如果最新的 超出分数=最新分数-上次分数-限制分数....
倒霉熊 2011-08-09
  • 打赏
  • 举报
回复


---想要的列名
学生姓名 语文上次分数 语文最新分数 语文老师评语 语文限制分数 语文超出分数 数学上次分数 数学最新分数 数学老师评语 数学限制分数 数学超出分数 物理上次分数 物理最新分数 物理老师评语 物理限制分数 物理超出分数

张三 74 90 及格 5 1
倒霉熊 2011-08-09
  • 打赏
  • 举报
回复
create table tb1 (sname varchar(10),classname varchar(10),oldcores int,nowcores int,note varchar(20))
go
insert into tb1 values('张三','语文',74,90,'及格')
insert into tb1 values('张三','数学',83,20,'更差')
insert into tb1 values('张三','物理',93,100,'不错')
insert into tb1 values('李四','语文',74,74,'随便')
insert into tb1 values('李四','数学',84,90,'还行')
insert into tb1 values('李四','物理',94,40,'差劲')
go
select * from tb1



表结构和数据,等下说要的效果
如此疲惫 2011-08-09
  • 打赏
  • 举报
回复

好多人等你呢
倒霉熊 2011-08-09
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 acherat 的回复:]
楼主建议你把你的问题模拟下环境,发个测试形式的数据结构和数据记录上来!

例如你有两个相关的表,就建立两个,tb1 tb2,列什么的都模拟下你原本的问题。
[/Quote]

明白啦,稍等
AcHerat 2011-08-09
  • 打赏
  • 举报
回复
不都说了么,你按照你的需求建立两个测试的表结构,数据自己往里加些,例如你可以把你这个问题建立两个表tb1 tb2,然后在tb1中建立你其中一个表相关的列,tb2同样,数据不一定要全是表中的,自己随便写些也可以啊!只要能将你这个复杂的问题简单化就行。
倒霉熊 2011-08-09
  • 打赏
  • 举报
回复
下面这句SQL是得到图片中数据的语句,至于测试数据,我没发给您导出来呀


--筛选信息
select
b.SO_SI_ID,a.SO_ItemNo,a.SO_ProcessID,a.SO_ProcessName,b.SO_SI_StepName,b.SO_SI_GetTime,b.SO_SI_CompTime,b.SO_SI_Notes,b.SO_SI_Optiontor into #so_stepList
from
SO_ProcessInfo a inner join SO_StepsInfo b on a.SO_ProcessID = b.SO_SI_ProcessID and a.SO_ProcessName = b.SO_SI_ProcessName
chuanzhang5687 2011-08-09
  • 打赏
  • 举报
回复
有时候技术是次要的,沟通才是 第一位!要善于把你的问题表达出来,而且让人很容易理解!
如此疲惫 2011-08-09
  • 打赏
  • 举报
回复

复杂的问题 尽量简单点的数据来描述 例如楼上所说的 tb1 tb2 然后 比如我想把其中一个什么列怎么装换成什么样子 这样好方便大家帮你测试同时解决问题
倒霉熊 2011-08-09
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 fredrickhu 的回复:]
亲 给我们测试数据和所需要的结果

在给结果的时候再说明怎么得到的结果
[/Quote]

测试数据咋给呀...我只能给创建表的语句给你,或者你给邮箱地址给我,我给库发给你,就这两张表。
--小F-- 2011-08-09
  • 打赏
  • 举报
回复
亲 给我们测试数据和所需要的结果

在给结果的时候再说明怎么得到的结果
倒霉熊 2011-08-09
  • 打赏
  • 举报
回复
上面的查询结果是两张表查询出来的结果,下面是表结构
if exists (select 1
from sysobjects
where id = object_id('SO_ProcessInfo')
and type = 'U')
drop table SO_ProcessInfo
go

/*==============================================================*/
/* Table: SO_ProcessInfo */
/*==============================================================*/
create table SO_ProcessInfo (
SO_PID int identity,
SO_ProcessID int null,
SO_ProcessName nvarchar(50) null,
SO_userName nvarchar(50) null,
SO_Optiontors nvarchar(50) null,
SO_ProcessSites int null,
SO_GUID nvarchar(50) null,
SO_ItemNo nvarchar(50) null,
SO_IsCompeted nvarchar(20) null,
constraint PK_SO_PROCESSINFO primary key (SO_PID)
)
go


execute sp_addextendedproperty 'MS_Description', '流程主表', 'user', 'dbo', 'table', 'SO_ProcessInfo', NULL, NULL
go


execute sp_addextendedproperty
'MS_Description', '主编号', 'user', 'dbo', 'table', 'SO_ProcessInfo', 'column', 'SO_PID'
go


execute sp_addextendedproperty
'MS_Description', '流程实例号', 'user', 'dbo', 'table', 'SO_ProcessInfo', 'column', 'SO_ProcessID'
go


execute sp_addextendedproperty
'MS_Description', '流程名', 'user', 'dbo', 'table', 'SO_ProcessInfo', 'column', 'SO_ProcessName'
go


execute sp_addextendedproperty
'MS_Description', '发起人帐号', 'user', 'dbo', 'table', 'SO_ProcessInfo', 'column', 'SO_userName'
go


execute sp_addextendedproperty
'MS_Description', '发起人', 'user', 'dbo', 'table', 'SO_ProcessInfo', 'column', 'SO_Optiontors'
go


execute sp_addextendedproperty
'MS_Description', '流程状态', 'user', 'dbo', 'table', 'SO_ProcessInfo', 'column', 'SO_ProcessSites'
go


execute sp_addextendedproperty
'MS_Description', 'GUID', 'user', 'dbo', 'table', 'SO_ProcessInfo', 'column', 'SO_GUID'
go


execute sp_addextendedproperty
'MS_Description', 'ItemNo', 'user', 'dbo', 'table', 'SO_ProcessInfo', 'column', 'SO_ItemNo'
go


execute sp_addextendedproperty
'MS_Description', '是否已完成', 'user', 'dbo', 'table', 'SO_ProcessInfo', 'column', 'SO_IsCompeted'
go



第二张表

if exists (select 1
from sysobjects
where id = object_id('SO_StepsInfo')
and type = 'U')
drop table SO_StepsInfo
go

/*==============================================================*/
/* Table: SO_StepsInfo */
/*==============================================================*/
create table SO_StepsInfo (
SO_SI_ID int identity,
SO_SI_ProcessName nvarchar(50) null,
SO_SI_ProcessID int null,
SO_SI_StepName nvarchar(50) null,
SO_SI_GetTime nvarchar(50) null,
SO_SI_CompTime nvarchar(50) null,
SO_SI_ISPlan nvarchar(50) null,
SO_SI_ISReview nvarchar(50) null,
SO_SI_Optiontor nvarchar(50) null,
SO_SI_LoginName nvarchar(50) null,
SO_SI_Notes nvarchar(1000) null,
SO_PID int null,
constraint PK_SO_STEPSINFO primary key (SO_SI_ID)
)
go


execute sp_addextendedproperty 'MS_Description', 'SO_StepsInfo', 'user', 'dbo', 'table', 'SO_StepsInfo', NULL, NULL
go


execute sp_addextendedproperty
'MS_Description', '步骤信息表主编号', 'user', 'dbo', 'table', 'SO_StepsInfo', 'column', 'SO_SI_ID'
go


execute sp_addextendedproperty
'MS_Description', '流程名', 'user', 'dbo', 'table', 'SO_StepsInfo', 'column', 'SO_SI_ProcessName'
go


execute sp_addextendedproperty
'MS_Description', '流程实例号', 'user', 'dbo', 'table', 'SO_StepsInfo', 'column', 'SO_SI_ProcessID'
go


execute sp_addextendedproperty
'MS_Description', '步骤名', 'user', 'dbo', 'table', 'SO_StepsInfo', 'column', 'SO_SI_StepName'
go


execute sp_addextendedproperty
'MS_Description', '接受时间', 'user', 'dbo', 'table', 'SO_StepsInfo', 'column', 'SO_SI_GetTime'
go


execute sp_addextendedproperty
'MS_Description', '更新时间', 'user', 'dbo', 'table', 'SO_StepsInfo', 'column', 'SO_SI_CompTime'
go


execute sp_addextendedproperty
'MS_Description', '是否需要策划', 'user', 'dbo', 'table', 'SO_StepsInfo', 'column', 'SO_SI_ISPlan'
go


execute sp_addextendedproperty
'MS_Description', '是否需要实物评审', 'user', 'dbo', 'table', 'SO_StepsInfo', 'column', 'SO_SI_ISReview'
go


execute sp_addextendedproperty
'MS_Description', '操作人', 'user', 'dbo', 'table', 'SO_StepsInfo', 'column', 'SO_SI_Optiontor'
go


execute sp_addextendedproperty
'MS_Description', '登录名', 'user', 'dbo', 'table', 'SO_StepsInfo', 'column', 'SO_SI_LoginName'
go


execute sp_addextendedproperty
'MS_Description', '备注', 'user', 'dbo', 'table', 'SO_StepsInfo', 'column', 'SO_SI_Notes'
go


execute sp_addextendedproperty
'MS_Description', '流程主表ID', 'user', 'dbo', 'table', 'SO_StepsInfo', 'column', 'SO_PID'
go
AcHerat 2011-08-09
  • 打赏
  • 举报
回复
楼主建议你把你的问题模拟下环境,发个测试形式的数据结构和数据记录上来!

例如你有两个相关的表,就建立两个,tb1 tb2,列什么的都模拟下你原本的问题。
倒霉熊 2011-08-09
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 acherat 的回复:]
你的限制周期怎么来的,建议把相关表的结构和测试数据发上来!
[/Quote]

限制周期,是根据步骤名称来的,比如记录中 LOB 的限制周期为10个小时,LOB确认为5个小时

步骤名称列的记录,是固定的,只会少,不会多。
倒霉熊 2011-08-09
  • 打赏
  • 举报
回复
描述的不清楚,嗯,如果各位还有什么问题可以问,或者留下邮箱,我给备份的数据库还有需要的效果发给大家。这里是我的代码,大家参考下,也只是得出了前面步骤四个列的结果,

--筛选信息
select
b.SO_SI_ID,a.SO_ItemNo,a.SO_ProcessID,a.SO_ProcessName,b.SO_SI_StepName,b.SO_SI_GetTime,b.SO_SI_CompTime,b.SO_SI_Notes,b.SO_SI_Optiontor into #so_stepList
from
SO_ProcessInfo a inner join SO_StepsInfo b on a.SO_ProcessID = b.SO_SI_ProcessID and a.SO_ProcessName = b.SO_SI_ProcessName
-----查询步骤信息
select SO_SI_StepName INTO #STEPNAME from #so_stepList
declare @sql varchar(max)
set @sql = 'select SO_ProcessID,SO_ItemNo'
---获取时间
select @sql = @sql+',max(case SO_SI_StepName when '''+ SO_SI_StepName +''' then SO_SI_GetTime else '''' end) ['+SO_SI_StepName+'获取时间]'
from #STEPNAME
---完成时间
select @sql = @sql+',max(case SO_SI_StepName when '''+ SO_SI_StepName +''' then SO_SI_CompTime else '''' end) ['+SO_SI_StepName+'完成时间]'
from #STEPNAME
--处理人
select @sql = @sql+',max(case SO_SI_StepName when '''+ SO_SI_StepName +''' then SO_SI_Optiontor else '''' end) ['+SO_SI_StepName+'处理人]'
from #STEPNAME
--备注
select @sql = @sql+',max(case SO_SI_StepName when '''+ SO_SI_StepName +''' then SO_SI_Notes else '''' end) ['+SO_SI_StepName+'备注]'
from #STEPNAME
--延迟时间
select @sql = @sql+',max(case SO_SI_StepName when '''+ SO_SI_StepName +''' then cast(datediff(hour,SO_SI_GetTime,SO_SI_CompTime) as nvarchar(50)) else ''0'' end) ['+SO_SI_StepName+'延迟时间]'
from #STEPNAME
set @sql = @sql+' from #so_stepList group by SO_ProcessID,SO_ItemNo'
exec(@sql)
DROP TABLE #STEPNAME
DROP TABLE #so_stepList
chuanzhang5687 2011-08-09
  • 打赏
  • 举报
回复
分好多!
AcHerat 2011-08-09
  • 打赏
  • 举报
回复
你的限制周期怎么来的,建议把相关表的结构和测试数据发上来!

22,209

社区成员

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

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