求sql语句(行变列的问题)

nk912114 2005-07-13 10:24:31
和上次的问题很相似,可我还是没有写出来 -_-
上次问题:http://community.csdn.net/Expert/topic/3857/3857324.xml?temp=.3852198
-----------------------------
有两表

表Drug(药物表)

DrugName DrugCode
西药费 a
中药费 b
草药费 c
... ...
表DrugFare(药物费用表)

PersonName DrugFare DrugCode
张三 50.0 a
张三 100.0 b
李四 60.0 a
...
现在要的结果如下:

DrugName 张三 李四 ...
西药费 50.0 60.0 ...
中药费 100.0 0.0 ...
草药费 0.0 0.0 ...
...
人员的某费用如果没有记录,则为0.0

谢谢!
...全文
457 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
zjcxc 元老 2005-07-14
  • 打赏
  • 举报
回复
--建立测试环境
Create Table Drug(DrugName Nvarchar(10),DrugCode Nvarchar(10))
Insert Drug Select N'西药费','a'
Union All Select N'中药费','b'
Union All Select N'草药费','c'

Create table DrugFare(PersonName Nvarchar(10),DrugFare Numeric(10,1),DrugCode Nvarchar(10))
Insert DrugFare Select N'张三',50.0, 'a'
Union All Select N'张三',100.0,'b'
Union All Select N'李四',60.0 ,'a'
GO

--处理
DECLARE @sqlhead nvarchar(4000),@sqlend nvarchar(4000)
,@sql1 nvarchar(4000),@sql2 nvarchar(4000),@sql3 nvarchar(4000),@sql4 nvarchar(4000)
,@i int,@ic nvarchar(10)

--生成数据处理临时表
SELECT id=IDENTITY(int,0,1),
g=0,
a=CAST(',SUM(Case When B.PersonName=N'''+PersonName +''' Then DrugFare Else 0 End ) As '+ PersonName
as nvarchar(4000))
INTO # FROM(
Select Distinct PersonName from DrugFare)a

--分组临时表
UPDATE a SET @i=id/i,g=@i
FROM # a,(SELECT i=3800/MAX(LEN(a)) FROM #)b
SET @ic=@i

--生成数据处理语句
SELECT
@sqlhead=N''''
+REPLACE(N'Select A.DrugName',N'''',N'''''')
+'''',
@sqlend=N''''
+REPLACE(N' from Drug A Left Join DrugFare B On A.DrugCode=B.DrugCode Group By A.DrugName',N'''',N'''''')
+N'''',
@sql1=N'',@sql2=N'',@sql3=N'',@sql4=N''
WHILE @ic>=0
SELECT
@sql1=N',@'+@ic+N' nvarchar(4000)'+@sql1,
@sql2=N',@'+@ic+N'=N'''''+@sql2,
@sql3=N',@'+@ic
+N'=CASE g WHEN '+@ic
+N' THEN @'+@ic+N'+a ELSE @'+@ic
+N' END'+@sql3,
@sql4=N'+@'+@ic+@sql4,
@ic=@ic-1
SELECT
@sql1=STUFF(@sql1,1,1,N''),
@sql2=STUFF(@sql2,1,1,N''),
@sql3=STUFF(@sql3,1,1,N''),
@sql4=STUFF(@sql4,1,1,N'')

--执行
EXEC(N'DECLARE '+@sql1+N'
SELECT '+@sql2+N'
SELECT '+@sql3+N' FROM #
EXEC(N'+@sqlhead+N'+'+@sql4+N'+N'+@sqlend+N')')
--删除临时表
DROP TABLE #
GO

--删除测试环境
Drop Table Drug,DrugFare
wscft 2005-07-14
  • 打赏
  • 举报
回复
楼主要实现诸如
DrugName 张三 李四 ...
西药费 50.0 60.0 ...
写在同一行。 我想用一条SQL 语句实现起来是很难的!
mengzulin 2005-07-14
  • 打赏
  • 举报
回复

EXEC(@S1+@S2+@S3+@S4+@S5)
来执行.
nk912114 2005-07-14
  • 打赏
  • 举报
回复
我用的paoluo(一天到晚游泳的鱼) 方法可以实现
但有新问题来了
因为数据库中的记录太多,这样的话那个动态sql语句长度超过了8000,sql语句别自动截取了
请问这种情况怎么解决??

新问题开的帖子:
http://community.csdn.net/Expert/topic/4143/4143434.xml?temp=.6065332

thanks!
nk912114 2005-07-14
  • 打赏
  • 举报
回复
谢谢大家
我用的paoluo(一天到晚游泳的鱼) 方法可以实现
但有新问题来了
因为数据库中的记录太多,这样的话那个动态sql语句长度超过了8000,sql语句别自动截取了
请问这种情况怎么解决??
mengzulin 2005-07-14
  • 打赏
  • 举报
回复
--看一下这个例子
if object_id('tab_1') is not null drop table tab_1
go
create table tab_1(id int, name varchar(10), value int, content varchar(10))
insert tab_1 select 1, 'ss', 8, null
union all select 1, 'dd', 9, 'aaa'
union all select 1, 'ff', 10, null
union all select 1, 'ss', 9, 'bb'
union all select 2, 'dd', 8, null
union all select 2, 'ee', 10, 'cc'
--创建用户自定义函数
if object_id('fun_vcontent') is not null drop function dbo.fun_vcontent
go
create function fun_vcontent( @id int, @name varchar(10))
returns varchar(100)
as
begin
declare @str varchar(100)
set @str=''
select @str=@str+','+convert(varchar(10), value)+coalesce('('+content+')'
, '')
from tab_1
where id=@id and name=@name

set @str=stuff(@str, 1, 1, '')
return @str
end
go
--中间结果
select t1.id, t1.name, t2.vcontent
from (select *
from (select distinct name from tab_1)t11,
(select distinct id from tab_1)t12) t1 left join
(select distinct id,name, dbo.fun_vcontent(id, name) as vcontent
from tab_1) t2 on t1.name=t2.name and t1.id=t2.id
order by t1.id, t1.name
Well 2005-07-14
  • 打赏
  • 举报
回复
用case when then可以解決
再加動態語句
wwwwb 2005-07-14
  • 打赏
  • 举报
回复
简单一点:
SELECT DrugName,SUM(case when PersonName='张三' then DrugFare esle 0000.00 end) 张三,SUM(case when PersonName='李四'then DrugFare else 0000.00 end) 李四 from
(SELECT qq2.*,qq1.DrugName FROM qq2 RIGHT JOIN qq1 ON qq1.DrugCode=qq2.DrugCode) b GROUP BY DrugName
nk912114 2005-07-14
  • 打赏
  • 举报
回复
谢谢大家
zjcxc 元老 2005-07-14
  • 打赏
  • 举报
回复
测试数据很少,楼主可以把我的搬到真实环境去测试
ccghghgj 2005-07-13
  • 打赏
  • 举报
回复
恩,楼上强!


================================================================
此帖通过csdn小助手回复。
CSDN小助手是使用vb.net编写的CSDN论坛脱机“外挂”,她能够在
脱离IE的情况下使用Csdn论坛。程序只加载最核心的数据,所以显示更
快,产生的流量更小。

下载地址:http://qqwwee.com/csdn.rar
================================================================
paoluo 2005-07-13
  • 打赏
  • 举报
回复
因为你的PersonName是动态的,所以要用动态SQL语句。
paoluo 2005-07-13
  • 打赏
  • 举报
回复
--建立测试环境
Create Table Drug(DrugName Nvarchar(10),DrugCode Nvarchar(10))
Insert Drug Select N'西药费','a'
Union All Select N'中药费','b'
Union All Select N'草药费','c'

Create table DrugFare(PersonName Nvarchar(10),DrugFare Numeric(10,1),DrugCode Nvarchar(10))
Insert DrugFare Select N'张三',50.0, 'a'
Union All Select N'张三',100.0,'b'
Union All Select N'李四',60.0 ,'a'
GO
--测试
Declare @S Nvarchar(4000)
Set @S='Select A.DrugName '
Select @S=@S+',SUM(Case When B.PersonName=N'''+PersonName +''' Then DrugFare Else 0 End ) As '+ PersonName
from (Select Distinct PersonName from DrugFare) A
Select @S=@S+' from Drug A Left Join DrugFare B On A.DrugCode=B.DrugCode Group By A.DrugName'
EXEC(@S)
--删除测试环境
Drop Table Drug,DrugFare
--结果
/*
DrugName 张三 李四
中药费 100.0 .0
草药费 .0 .0
西药费 50.0 60.0
*/
ccghghgj 2005-07-13
  • 打赏
  • 举报
回复
我公司有相关的代码,明天发给你啊!


================================================================
此帖通过csdn小助手回复。
CSDN小助手是使用vb.net编写的CSDN论坛脱机“外挂”,她能够在
脱离IE的情况下使用Csdn论坛。程序只加载最核心的数据,所以显示更
快,产生的流量更小。

下载地址:http://qqwwee.com/csdn.rar
================================================================
YuyuanJian 2005-07-13
  • 打赏
  • 举报
回复
这是交差表,用一条语句很难!

34,593

社区成员

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

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