表反转的两种方式

在开发过程中,往往会遇到需要对一个表进行统计汇总,并生成统计报表的问题,这些时候,往往要用到所谓的“表反转”操作。
例如:
有用户查询表,表结构如下:
CREATE TABLE [dbo].[WhiteList_QueryLog](
  [AccountID] [varchar](50) COLLATE Chinese_PRC_CI_AI NULL,
  [ResponseString] [nvarchar](150) COLLATE Chinese_PRC_CI_AI NOT NULL,
 ) 
希望通过ResponseString字段的第一个字符来统计一下accountID操作成功,失败,以及异常的次数,并生成如下形式的表格
 
AccountID ok fail exception
xxx 1 0 2
 
本文介绍自己用过的两种解决方案:
1. pivot(仅限SQL Server 2005+版本)
 
SELECT
AccountID,
fail,exception,ok
FROM (
SELECT 
q.AccountID
CASE WHEN SUBSTRING(q.ResponseString,1,1) = '0' THEN 'fail'
WHEN SUBSTRING(q.ResponseString,1,1) = '1' THEN 'ok'
WHEN SUBSTRING(q.ResponseString,1,1) = '-' THEN 'exception'
END AS Result
 FROM WhiteList_QueryLog q
) AS D PIVOT (COUNT (Result) FOR Result IN (fail,ok,exception)) AS P
/////////////////////////////////////////////////////////////////////////////////////////////////////////
pivot是SQL Server 2005新提供的表运算符,它的工作过程如下:
1)将左输入D中所有未在PIVOT表达式中出现的列(本例为q.AccountID)对D进行隐式分组(如果D中的所有字段都出现在PIVOT表达式中,则忽略此步,2)中将对全表做聚集操作)
2)对分组之后的结果进行PIVOT指定的聚集操作,即分别对Result中值在(fail,ok,exception)集合的记录进行COUNT操作,将结果作为对应列的值(fail,exception或者ok列
由于只有SQL Server 2005+版本支持PIVOT操作,所以以上方法并不通用。
 
2.
SELECT q.MobileNo, q.AccountID, q.Version,q.ResponseString,
 CASE WHEN SUBSTRING(q.ResponseString,1,1) = '0' THEN 'fail'
 WHEN SUBSTRING(q.ResponseString,1,1) = '1' THEN 'ok'
 WHEN SUBSTRING(q.ResponseString,1,1) = '-' THEN 'exception'
END AS Result
FROM WhiteList_QueryLog q
into #T
SELECT accountid, min(case  result when 'fail' then  [count] end) fail,
       min(case  result when 'ok' then  [count] end) ok,
       min(case  result when 'exception' then  [count] end) exception
 FROM (SELECT accountid, COUNT(1) [count],result FROM #T
       GROUP BY accountid, result) s
GROUP BY accountid
 这种方法相当于一个显式分组,即PIVOT隐式分组的操作(依据q.AccountID)要我们显式来表达,值得注意的地方是:case  result when 'fail' then  [count] end这种表达方式相当于为min所操作的count字段多加了一个限制,就是result字段必须为'fail'
这种方式的优点就是通用性强,SQl Server和Oracle都可以使用。
 

posted on 2010-05-28 18:43  Chrisnda  阅读(1509)  评论(1编辑  收藏  举报

导航