两个表的结构如下:
一、费用类型表:
项目号      项目名称      费用类型
1           西药费       3,4,7,8 
2           中草药费       5,6
3           化验费       10,11,13,14,15
......
二、费用表:
病人号     核算方法     费用类型      费用
1102         0          3            1.55
1102         0          10           3.50
1102         4           9           5.05
1103         0          4            20.58
1103         4          9            20.58
......
现在是这样:
select 西药费=sum(cast when 费用类型 in(select 费用类型 from 费用类型表 where 项目号=1 then 费用 else NULL end)),
中草药费=sum(cast when 费用类型 in(select 费用类型 from 费用类型表 where 项目号=2 then 费用 else NULL end)),
化验费=sum(cast when 费用类型 in(select 费用类型 from 费用类型表 where 项目号=3 then 费用 else NULL end))
 from 费用表 where 核算方法=0问题:一、其中:‘西药费’,‘中草药费’,‘化验费’是从费用类型表中提取的,这样的动态字段如何从表‘费用类型表’动态得到。
二、但是上面的写法是不行的,用
charindex(','+cast(费用类型 as varchar(4))+',',','+@text+',')>0 可以。
总而言之,我该如何用表“费用类型表”的‘项目名称’和‘费用类型’来查询表‘费用表’里对应项目的费用呢?

解决方案 »

  1.   

    create table #t1(项目号 int,项目名称 varchar(10),费用类型 varchar(20))
    insert into #t1 select 1,'西药费'  ,'3,4,7,8' 
    insert into #t1 select 2,'中草药费','5,6'
    insert into #t1 select 3,'化验费'  ,'10,11,13,14,15'create table #t2(病人号 int,核算方法 int,费用类型 int,费用 numeric(5,2))
    insert into #t2 select 1102,0,3 ,1.55
    insert into #t2 select 1102,0,10,3.50
    insert into #t2 select 1102,4,9 ,5.05
    insert into #t2 select 1103,0,4 ,20.58
    insert into #t2 select 1103,4,9 ,20.58declare @s varchar(8000)
    set @s=''
    select @s=@s+','+项目名称+'=sum(case when charindex('',''+rtrim(费用类型)+'','','','+rtrim(费用类型)+','')>0 then 费用 else 0 end)'
    from #t1 order by 项目号set @s='select '+stuff(@s,1,1,'')+' from #t2'exec(@s)/*
    西药费      中草药费    化验费
    ----------  ----------  ---------------------------------------- 
    22.13       0.00        3.50
    */drop table #t1,#t2
      

  2.   

    declare @a table(项目号 int,项目名称 varchar(10),费用类型 varchar(50))insert @a select 1,'西药费','3,4,7,8' union all 
    select 2,'草药费','5,6' union all 
    select 3,'化验费','10,11,13,14,15'declare @b table(病人号 int,核算方法 char(1),费用类型 char(3),费用 numeric(18,4))
    insert @b select 1102,'0','3',1.55 union all
    select 1102,'0','10',3.50 union all
    select 1102,'4','9',5.05 union all
    select 1103,'0','4',20.58 union all
    select 1103,'4','9',20.58select 项目号,项目名称,substring(费用类型,N,charindex(',',费用类型 +',',N)-N) as 费用类型
    into #
    from @a a,
    (select 1 as N
    union all select 2
    union all select 3
    union all select 4
    union all select 5
    union all select 6
    union all select 7
    union all select 8
    union all select 9
    union all select 10
    union all select 11) b 
    where substring(','+费用类型,N,1)= ',' 
    select a.项目名称,sum(b.费用) as 费用
     from @b b
    left join  # a
    on a.费用类型 = b.费用类型
     where b.核算方法='0'
    group by a.项目名称
    drop table #/*项目名称       费用                                       
    ---------- ---------------------------------------- 
    化验费        3.5000
    西药费        22.1300*/
      

  3.   

    declare @Select varchar(10),@FieldList varchar(5000),@From varchar(100),@Where varchar(255),@Field1 varchar(50),@Field2 varchar(50),@Field3 varchar(255)
    select @Select='select'
    select @FieldList=''
    select @From='From [费用表] a'
    select @Where='where [核算方法]=0'declare temp_Cursor cursor for 
    select [项目号],[项目名称],[费用类型] from [费用类型表]open temp_Cursor
    fetch next from temp_Cursor into @Field1,@Field2,@Field3
    while @@fetch_status=0
    begin
       if @FieldList<>'' then @FieldList=@FieldList+','
       select @FieldList='sum(case when [费用类型] in ('+@Field3+')) then [费用] else 0 end) as '+@Field2
       fetch next from temp_Cursor into @Field1,@Field2,@Field3
    end
    execute(@Select+' '+@FieldList+' '+@From+' '+@Where)
      

  4.   

    close temp_Cursor
    deallocate temp_Cursor
      

  5.   

    同意happyflystone(没枪的狙击手)的说法
    这样的数据库表结构建得极不合理
    老大们不要一味地针对问题做解答,而是要先看出问题描述是不是正确。
    对于关系模型规范化理论,上面的问题完全违反了规范,所以才会出现不能查询而是非要用游标解决的现象。
    如果老大们真能解决问题,请把以上
    费用类型表的费用类型列上进行插入/删除/查找都做出来,那我就佩服了。所以如果把表结构改成:
    项目号      项目名称      费用类型
    1           西药费       3
    1           西药费       4
    1           西药费       7
    1           西药费       8 
    2           中草药费     5
    2           中草药费     6
    3           化验费       10
    3           化验费       11
    3           化验费       13
    3           化验费       15这样的话,插入/删除/查找都能很容易地实现且统计也不成问题,这样才是对楼主问题最好的解决。
      

  6.   

    楼上的见解有所偏颇,"费用类型表"是用户可以定义的费别,是个基础字典.
    感谢happyflystone(没枪的狙击手)和unsigned(僵哥(送人以鱼,不如授人渔;授人以渔,不如渔人之鱼)) 两位老大.
      

  7.   

    看走眼了,对不起,还要感谢"libin_ftsafe(子陌红尘)".
      

  8.   

    libin_ftsafe(子陌红尘) 的方法很好,语法简洁,但是比较慢。
    happyflystone(没枪的狙击手)的
    select 项目号,项目名称,substring(费用类型,N,charindex(',',费用类型 +',',N)-N) as 费用类型
    into #
    from @a a,
    (select 1 as N
    union all select 2
    union all select 3
    union all select 4
    union all select 5
    union all select 6
    union all select 7
    union all select 8
    union all select 9
    union all select 10
    union all select 11) b 
    where substring(','+费用类型,N,1)= ',' 
    比较烦琐,类型多怎么办?unsigned(僵哥(送人以鱼,不如授人渔;授人以渔,不如渔人之鱼))利用游标,测试没成功,
    说是then附近有语法错误。