有如下形式的表mytable2:
ID TYPE SUBTYPE COUNT MONTH 1 A Z 1 7/1/2008 1 A Z 3 7/1/2008 2 B C 2 7/2/2008 1 A Z 3 7/2/2008
我能否用SQL查询得到如下的输出:
ID A_Z B_C MONTH 1 4 0 7/1/2008 2 0 2 7/2/2008 1 0 3 7/2/2008
这样,TYPE和SUBTYPE合并成新的列,而COUNT列根据ID,MONTH分组求和。
注意:这里假设我们有100多这样的TYPES和SUBTYPES,所以如果在SQL中硬编码A和Z可能并不是非常有效。这样的SQL如何实现呢?这里RDBMS为SQLServer。
本题来源stackoverflow
本题第一眼看的时候,我们能想到用case when来实现行转列以及求和的需求,但是由于TYPES和SUBTYPES数量大,我们可以试试SQLServer 2005的Pivot,当然依然需要拼接动态SQL。具体如下:
/*声明三个字符变量,都用于保存拼接出的字符串结果*/ declare @sql as varchar(max) declare @pivot_list as varchar(max) -- leave null for coalesce technique declare @select_list as varchar(max) -- leave null for coalesce technique /*加号+实现concat拼接字符串的功能;coalesce处理null*/ select @pivot_list = coalesce(@pivot_list + ', ', '') + '[' + pivot_code + ']' ,@select_list = coalesce(@select_list + ', ', '') + 'isnull([' + pivot_code + '], 0) as [' + pivot_code + ']' from ( select distinct concat(type, '_', subtype) as pivot_code from mytable2 ) as pivot_codes set @sql = ' ;with p as ( select id, [month], [type] + ''_'' + subtype as pivot_code, sum([count]) as [count] from mytable2 group by id, [month], [type] + ''_'' + subtype ) select id, [month], '' + @select_list + '' from p pivot ( sum([count]) for pivot_code in ( '' + @pivot_list + '' ) ) as pvt ' /*执行生成的动态SQL*/ exec (@sql)
上述方法,首先使用子查询表pivot_codes找出所有不同的合并列,并利用其生成拼接字符串。然后利用pivot进行行转列的操作和sum操作。
由于语句动态生成,其实也可以类似上述方式拼接成case when语句,但是相较pivot的使用比较笨拙,在其他RDBMS下可以考虑尝试。
The post 能否实现行转列(Pivot),并且合并列? appeared first on SQLParty.