项目中有这样一个需求:分时段显示用户的好评、中评、差评,如图所示:

在MSSQL2005之后,MS给出两个运算符: PIVOT和UNPIVOT,文档给出的说明是:
可以使用 PIVOT 和 UNPIVOT 关系运算符将表值表达式更改为另一个表。PIVOT 通过将表达式某一列中的唯一值转换为输出中的多个列来旋转表值表达式,并在必要时对最终输出中所需的任何其余列值执行聚合。UNPIVOT 与 PIVOT 执行相反的操作,将表值表达式的列转换为列值。

利用这两个运算符可方便得到想要的结果,你还在使用大量的CASE..WHEN..THEN吗?
贴上具体的SQL:
 1 CREATE TABLE ##Rep(
2 [Point] [int] NULL,
3 [Time] [datetime] NULL,
4 );
5
6 INSERT INTO ##Rep([Point],[Time])VALUES(1,'2010-11-11');
7 INSERT INTO ##Rep([Point],[Time])VALUES(2,'2011-08-11');
8 INSERT INTO ##Rep([Point],[Time])VALUES(3,'2011-11-11');
9 INSERT INTO ##Rep([Point],[Time])VALUES(1,'2012-01-14');
10 INSERT INTO ##Rep([Point],[Time])VALUES(1,'2012-01-01');
11 INSERT INTO ##Rep([Point],[Time])VALUES(3,'2012-01-02');
12 INSERT INTO ##Rep([Point],[Time])VALUES(3,'2011-09-11');
13
14 SELECT * FROM
15 (
16 SELECT POINTS,TIMESPAN,POINT FROM
17 (SELECT '最近一星期' AS TIMESPAN, ISNULL(SUM(CASE WHEN Point = 1 THEN 1 ELSE 0 END),0) AS 好评,
18 ISNULL(SUM(CASE WHEN Point = 2 THEN 1 ELSE 0 END),0) AS 中评,
19 ISNULL(SUM(CASE WHEN Point = 3 THEN 1 ELSE 0 END),0) AS 差评
20 FROM ##Rep WHERE Time > dateadd(day,-7,GETDATE())
21 UNION ALL
22 SELECT '最近一个月' AS TIMESPAN, ISNULL(SUM(CASE WHEN Point = 1 THEN 1 ELSE 0 END),0) AS 好评,
23 ISNULL(SUM(CASE WHEN Point = 2 THEN 1 ELSE 0 END),0) AS 中评,
24 ISNULL(SUM(CASE WHEN Point = 3 THEN 1 ELSE 0 END),0) AS 差评
25 FROM ##Rep WHERE Time > dateadd(day,-30,GETDATE())
26 UNION ALL
27 SELECT '最近六个月' AS TIMESPAN, ISNULL(SUM(CASE WHEN Point = 1 THEN 1 ELSE 0 END),0) AS 好评,
28 ISNULL(SUM(CASE WHEN Point = 2 THEN 1 ELSE 0 END),0) AS 中评,
29 ISNULL(SUM(CASE WHEN Point = 3 THEN 1 ELSE 0 END),0) AS 差评
30 FROM ##Rep WHERE Time > dateadd(day,-180,GETDATE())
31 UNION ALL
32 SELECT '六个月之前' AS TIMESPAN, ISNULL(SUM(CASE WHEN Point = 1 THEN 1 ELSE 0 END),0) AS 好评,
33 ISNULL(SUM(CASE WHEN Point = 2 THEN 1 ELSE 0 END),0) AS 中评,
34 ISNULL(SUM(CASE WHEN Point = 3 THEN 1 ELSE 0 END),0) AS 差评
35 FROM ##Rep WHERE Time < dateadd(day,-180,GETDATE())
36 ) AS P
37 UNPIVOT
38 (POINT FOR POINTS IN (好评, 中评, 差评)) AS UN
39 ) T
40 PIVOT
41 (MAX(POINT) FOR TIMESPAN in ([最近一星期],[最近一个月],[最近六个月],[六个月之前]))AS PT;

结果:


 posted on 2012-01-16 00:49  k&H  阅读(238)  评论(0编辑  收藏  举报