• 全部
  • 基础类
  • 应用实例
  • 新技术前沿

如何将多行数据合并成一行多列,并将结果生成视图

Helen_YM 2008-03-18 03:05:13
例如:
1长春 1.标准全球通 234
1长春 2.全球通资费套餐 5423
1长春 3.全球通优惠 454
2吉林 1.标准全球通 297
2吉林 2.全球通资费套餐 12
2吉林 3.全球通优惠 29949

要生成的报表要是这样的:

地区 1.标准全球通 2.全球通资费套餐 3.全球通优惠
长春 234 5423 454
吉林 297 12 29949

根据以前的大人们的回复,我找到如下答案:
--建立测试环境
Create Table 表(区域 varchar(100),类型 varchar(100),价格 varchar(100))
--插入数据
insert into 表
select '1长春','1.标准全球通','234' union
select '1长春','2.全球通资费套餐','5423' union
select '1长春','3.全球通优惠','454' union
select '2吉林','1.标准全球通','297' union
select '2吉林','2.全球通资费套餐','12' union
select '2吉林','3.全球通优惠','29949'

--测试语句
DECLARE @SQL VARCHAR(8000)
SET @SQL='SELECT 区域'
SELECT @SQL= @SQL+
',min(CASE WHEN 类型 = ''' + 类型 + ''' THEN 价格 END) [' + 类型 + ']'
FROM (SELECT DISTINCT 类型 FROM 表) A
SET @SQL=@SQL+' FROM 表 GROUP BY 区域'
exec (@SQL)


--删除测试环境
Drop Table 表

但是,我现在的问题是,得到的结果集我需要能够生成视图,因为我需要和其它的视图关联生成一个结果集。
请问,怎么将这段代码生成视图呢?
不好意思,我太笨了,临门一脚,就是不知道怎么踢。
...全文
490 点赞 收藏 27
写回复
27 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
超级大笨狼 2008-03-20
在服务器端合并数据不是好办法,在客户端干这个才是优美的做法。
回复
超级大笨狼 2008-03-19
<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
<TITLE></TITLE>
</HEAD>
<BODY>
用inner Join可以做到一个表返回纪录,速度要快些。<br/>

select * from 主表 inner Join 从表 on 主表.外键=从表.id<br/>

如果要显示上合并行,可以在客户端合并<br/>

<TABLE WIDTH=75% BORDER=1 CELLSPACING=1 CELLPADDING=1 id="tb">
<TR id="row">
<TD id="td">1</TD>
<TD>a</TD>
<TD>b</TD>
</TR>
<TR>
<TD>1</TD>
<TD>c</TD>
<TD>d</TD>
</TR>
<TR>
<TD>1</TD>
<TD>c</TD>
<TD>d</TD>
</TR>
<TR>
<TD>2</TD>
<TD>e</TD>
<TD>f</TD>
</TR>
<TR>
<TD>2</TD>
<TD>e</TD>
<TD>f</TD>
</TR>
<TR>
<TD>2</TD>
<TD>e</TD>
<TD>f</TD>
</TR>
<TR>
<TD>2</TD>
<TD>e</TD>
<TD>f</TD>
</TR>
</TABLE>
<SCRIPT LANGUAGE=javascript>


var Rows=document.getElementById("tb").rows;
var Col=1;//这个是要合并的第几列;
var lastValue;

for(i=0;i<Rows.length;i++)
{
lastValue=Rows[i].cells[Col-1].innerHTML;
var same=1;

while(lastValue==Rows[i+same].cells[Col-1].innerHTML )
{
Rows[i+same].removeChild(Rows[i+same].cells[Col-1]);
same+=1;
if((i+same)==Rows.length )
{
break;
}
}

Rows[i].cells[Col-1].rowSpan=same;
i=i+same-1;
}
</SCRIPT>


</BODY>
</HTML>
回复
橘子香水 2008-03-19
用临时表比较方便.
回复
chyx413332087 2008-03-19
up
回复
ggy11687 2008-03-19
[Quote=引用 8 楼 Helen_YM 的回复:]
大师给的这个是能生成视图,但是,它,它,它,它还是是个静态的视图啊,我可能每次在使用这个视图的时候已经将表的记录更新了,我不能还使用这个旧视图啊。所以需要动态得到结果。
例如:
我有两个表
--建立测试环境
Create Table 表1(区域 varchar(100),姓名 varchar(100),地址 varchar(100))
--插入数据
insert into 表1
select '长春','张三','**街**号1' union
select '长春','李四','**街**号2' …
[/Quote]

应该是执行多表查询的吧,找到主外键就可以操作了啊
回复
JiangHongTao 2008-03-18
LZ 不识货呀,才给我6分
开个玩笑!!!!!!!!!!
回复
JiangHongTao 2008-03-18
[Quote=引用 17 楼 Helen_YM 的回复:]
用临时表根本不现实,如果我有两个人同时使用呢,每个人的搜索条件是不一样的。那得到的结果不就错误了吗?
[/Quote]
临时表是面向连接的,不同的用户临时表相互是不可见的,这就是为什么要用临时表而不用视图的原因,采用视图就会出现你所说的情况,要么会产生死锁。
回复
Helen_YM 2008-03-18
实在不好意思,我的分太少了,对不起各位了,希望下次能多点分散给大家。
回复
Helen_YM 2008-03-18
不好意思,刚刚看到大家的回复(囧,我忘记刷新页面了),我去试试,看看大家说的自动生成临时表行不行?
行吗?
不行吗?
我不知道啊。
回复
xiaoliaoyun 2008-03-18
不用视图是否可以,直接执行下面的语句

DECLARE @SQL VARCHAR(8000)
SET @SQL='SELECT 表1.姓名,表1.地址,A.* FROM(SELECT 区域'
SELECT @SQL= @SQL+
',min(CASE WHEN 类型 = ''' + 类型 + ''' THEN 价格 END) [' + 类型 + ']'
FROM (SELECT DISTINCT 类型 FROM 表2) A
SET @SQL=@SQL+' FROM 表2 GROUP BY 区域)A INNER JOIN 表1 ON 表1.区域 = A.区域'
EXEC (@SQL)
回复
Helen_YM 2008-03-18
用临时表根本不现实,如果我有两个人同时使用呢,每个人的搜索条件是不一样的。那得到的结果不就错误了吗?
回复
JiangHongTao 2008-03-18
--建立测试环境  
Create Table 表1(区域 varchar(100),姓名 varchar(100),地址 varchar(100))
--插入数据
insert into 表1
select '长春','张三','**街**号1' union
select '长春','李四','**街**号2' union
select '长春','王五','**街**号3' union
select '吉林','赵六','**街**号4' union
select '吉林','于七','**街**号5' union
select '吉林','吴八','**街**号6'
Create Table 表2(区域 varchar(100),类型 varchar(100),价格 varchar(100))
--插入数据
insert into 表2
select '长春','1.标准全球通','234' union
select '长春','2.全球通资费套餐','5423' union
select '长春','3.全球通优惠','454' union
select '吉林','1.标准全球通','297' union
select '吉林','2.全球通资费套餐','12' union
select '吉林','3.全球通优惠','29949'
go
--建动态转换存储过程
create proc vv
as
begin

DECLARE @SQL VARCHAR(8000)
select @sql = 'alter table #vv add 区域 varchar(100)'
select @sql = @sql + ' ,['+类型+'] varchar(100)' from 表2 group by 类型
exec(@sql)
alter table #vv drop column vvidvv
SET @SQL=' insert #vv SELECT 区域'
SELECT @SQL= @SQL+
',min(CASE WHEN 类型 = ''' + 类型 + ''' THEN 价格 END) [' + 类型 + ']'
FROM (SELECT DISTINCT 类型 FROM 表2) A
SET @SQL=@SQL+' FROM 表2 GROUP BY 区域'
exec (@SQL)
end
go

--调用
create table #vv(vvidvv int)
exec vv
select b.姓名,b.地址,a.* from #vv a,表1 b where a.区域 = b.区域
drop table #vv --别忘了清临时表
--调用结束
go
drop proc vv
go
Drop Table 表1,表2
/*
姓名 地址 区域 1.标准全球通 2.全球通资费套餐 3.全球通优惠
---------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------
李四 **街**号2 长春 234 5423 454
王五 **街**号3 长春 234 5423 454
张三 **街**号1 长春 234 5423 454
吴八 **街**号6 吉林 297 12 29949
于七 **街**号5 吉林 297 12 29949
赵六 **街**号4 吉林 297 12 29949
*/
回复
JiangHongTao 2008-03-18
其它的方式都有可能产生数据多用户冲突。
回复
JiangHongTao 2008-03-18
调用的时候只要建个领事表#vv
执行存储过程,数据就在这个临时表中了。
create table #vv(vvidvv int)--标准写法,不能改动,包括表名和字段名
exec vv --执行存储过程
select * from #vv --数据在#vv 表中了

由于采用的是临时表,因此不会产生多用户冲突。
回复
zhuyx808 2008-03-18

create PROCEDURE proc1

declare @sql varchar(8000)
set @sql = 'create view my_view as select 区域 '
select @sql = @sql + ' , max(case 类型 when ''' + 类型 + ''' then 价格 else 0 end) [' + 类型 + ']'
from (select distinct 类型 from 表) as a
set @sql = @sql + ' from 表 group by 区域'

exec(@sql)

select * from my_view//这里你还要关联其他表或视图

drop view my_view



页面中
需要视图的地方就调用这个存储过程
视图my_view只是在调用的时间段内出现,调用结束视图自然就没了,数据变化视图自然会变化

以前有个我发的相似的东西可能对你有所启发
http://topic.csdn.net/u/20080130/17/a0f2283b-fcf9-4170-a8f4-ec10ba104d9b.html
回复
JiangHongTao 2008-03-18
用临时表:
Create   Table   表(区域   varchar(100),类型   varchar(100),价格   varchar(100))    
--插入数据
insert into 表
select '1长春','1.标准全球通','234' union
select '1长春','2.全球通资费套餐','5423' union
select '1长春','3.全球通优惠','454' union
select '2吉林','1.标准全球通','297' union
select '2吉林','2.全球通资费套餐','12' union
select '2吉林','3.全球通优惠','29949'
go
create proc vv
as
begin

DECLARE @SQL VARCHAR(8000)
select @sql = 'alter table #vv add 区域 varchar(100)'
select @sql = @sql + ' ,['+类型+'] int' from 表 group by 类型
exec(@sql)
alter table #vv drop column vvidvv
SET @SQL=' insert #vv SELECT 区域'
SELECT @SQL= @SQL+
',min(CASE WHEN 类型 = ''' + 类型 + ''' THEN 价格 END) [' + 类型 + ']'
FROM (SELECT DISTINCT 类型 FROM 表) A
SET @SQL=@SQL+' FROM 表 GROUP BY 区域'
exec (@SQL)
end
go
create table #vv(vvidvv int)
exec vv
select * from #vv
drop table #vv
go
drop proc vv
go
Drop Table 表
回复
Helen_YM 2008-03-18
因为我需要在C#里面使用它来得到一个List显示,但是又不知道怎么动态,请大师详细讲讲各个步骤哈!嘿嘿。。。我是个脑筋不拐弯的人,您直白的告诉我吧。
回复
zhuyx808 2008-03-18
所以你在需要结果的时候不是通过调用视图,而是调用存储过程啊,在你调用存储过程的时候生成视图,调用结束视图就没了,什么时候调用什么时候生成视图的
回复
dawugui 2008-03-18
--如果不用静态的,就用如下动态的.
--建立测试环境 
Create Table 表(区域 varchar(100),类型 varchar(100),价格 varchar(100))
--插入数据
insert into 表
select '长春','1.标准全球通','234' union
select '长春','2.全球通资费套餐','5423' union
select '长春','3.全球通优惠','454' union
select '吉林','1.标准全球通','297' union
select '吉林','2.全球通资费套餐','12' union
select '吉林','3.全球通优惠','29949'
go

declare @sql varchar(8000)
set @sql = 'create view my_view as select 区域 '
select @sql = @sql + ' , max(case 类型 when ''' + 类型 + ''' then 价格 else 0 end) [' + 类型 + ']'
from (select distinct 类型 from 表) as a
set @sql = @sql + ' from 表 group by 区域'

exec(@sql)

select * from my_view

drop table 表
drop view my_view

/*
区域 1.标准全球通 2.全球通资费套餐 3.全球通优惠
-----------------------------------------------
长春 234 5423 454
吉林 297 12 29949

(所影响的行数为 2 行)
*/
回复
Helen_YM 2008-03-18
大师给的这个是能生成视图,但是,它,它,它,它还是是个静态的视图啊,我可能每次在使用这个视图的时候已经将表的记录更新了,我不能还使用这个旧视图啊。所以需要动态得到结果。
例如:
我有两个表
--建立测试环境
Create Table 表1(区域 varchar(100),姓名 varchar(100),地址 varchar(100))
--插入数据
insert into 表1
select '长春','张三','**街**号1' union
select '长春','李四','**街**号2' union
select '长春','王五','**街**号3' union
select '吉林','赵六','**街**号4' union
select '吉林','于七','**街**号5' union
select '吉林','吴八','**街**号6' union
go
Create Table 表2(区域 varchar(100),类型 varchar(100),价格 varchar(100))
--插入数据
insert into 表2
select '长春','1.标准全球通','234' union
select '长春','2.全球通资费套餐','5423' union
select '长春','3.全球通优惠','454' union
select '吉林','1.标准全球通','297' union
select '吉林','2.全球通资费套餐','12' union
select '吉林','3.全球通优惠','29949'
go

我需要得到结果
区域 姓名 地址 1.标准全球通 2.全球通资费套餐 3.全球通优惠
长春 张三 **街**号1 234 5423 454
长春 李四 **街**号2 234 5423 454
长春 王五 **街**号3 234 5423 454
吉林 赵六 **街**号4 297 12 29949
吉林 于七 **街**号5 297 12 29949
吉林 吴八 **街**号6 297 12 29949

而可能每次得到这个结果的时候,不见得后面的 1.标准全球通 2.全球通资费套餐 3.全球通优惠是固定的,有可能是 1.全球通 2.套餐 3.优惠 4.实际

所以,应该怎么做呢?

太长了,大家耐心的看看,帮帮我哈!谢谢了!
回复
加载更多回复
相关推荐
发帖
MS-SQL Server
创建于2007-09-28

3.3w+

社区成员

MS-SQL Server相关内容讨论专区
申请成为版主
帖子事件
创建了帖子
2008-03-18 03:05
社区公告
暂无公告