日期:2014-05-16  浏览次数:20587 次

关于数据库列转行的问题。
SQL SERVER 2005以后列转行有个函数可以直接用。
2000的数据库我当初做的时候用的是
select 日期,
max(case id when '列头A' then 值 end ) as 列头A,
max(case id when '列头B' then 值 end ) as 列头B,
max(case id when '列头C' then 值 end ) as 列头C,
max(case id when '列头D' then 值 end ) as 列头D
FROM (SELECT 日期,列头(包含ABCD),值 from table ) t1 group by thisd



SELECT 日期,列头(包含ABCD),值 from table
的查询结果是这样的
日期          列头    值
20140101      A       100
20140101      B       100
20140101      C       100
20140102      A       100
20140102      B       100
20140102      C       100
20140103      A       100
20140103      B       100 
20140103      C       100

我想知道这里的MAX到底是什么用处啊。。
除了因为配合GROUP BY 要用聚合包起来。
那换成MIN之类的不是一样效果么?

------解决方案--------------------
其实你那个查询应该是case when xx then 值 else null end 这样,而null比那个“值”小,所以用max,如果换min,就会显示null出来
------解决方案--------------------
ELSE else_result_expression
比较运算计算结果不为 TRUE 时返回的表达式。如果忽略此参数且比较运算计算结果不为 TRUE,则 CASE 返回 NULL。else_result_expression 是任意有效的表达式。else_result_expression 及任何 result_expression 的数据类型必须相同或必须是隐式转换的数据类型。
也就是说你的代码里面如果不符合case 条件,会返回null,null 比你的值小。
------解决方案--------------------
这个还要看你业务,比如“A”一天有几个值,你业务上求 sum ? 求 Max ? 求 Min.

所以要有个汇聚函数。
------解决方案--------------------
一般行转列,就是group by,然后对要转的列,用max,min,sum等聚合函数。

之所以要用这些聚合函数,是因为你的要转的列,不再group by中,如果不用聚合函数,就会报错,这里的max或者min,其实没有什么具体的意义,只是在group by的时候,不至于报错。

如果用sum,那么就不仅是行专列了,还可以进行 求和汇总。
------解决方案--------------------
比如,你可以类似这么写,求sum;

 declare @sql varchar(2000)
 set @sql='select ,'
 select @sql=@sql+'sum(case when 列头='''+列头+''' then 值 else 0 end)  as '+列头+','  from 
 (
 select distinct 列头 from 表名
 )tb
 set @sql=substring(@sql,1,len(@sql)-1)
 set @sql=@sql+' from 表名 group by 日期 '
------解决方案--------------------
引用:
Quote: 引用:

其实你那个查询应该是case when xx then 值 else null end 这样,而null比那个“值”小,所以用max,如果换min,就会显示null出来

我已经把所有的列头的出现的情况全部用WHEN CASE 列举出来的。
而每天产生的数据输固定条数,固定科目的。
那实际是否就是这个MAX只是起到为了GROUP BY 需要包在聚合函数而使用?


你的这个说法有些不理解。
就是说,假如用了你的语句。
然后我有一列没有包含在case when 语句里面。就会显示NULL 
实际显示就会这样?(假如C备有被枚举在CASE WHEN里面)
日期