好端端的,怎么又扯到透视表去了呢?手拿开,男男授受不亲,没事乱摸我额头作甚,哥没烧糊涂。我们之前说TRANSFROM语法如下:TRANSFORM aggfunction SELECT statement PIVOT pivotfield [IN (value1[, value2[, ...]])]以透视表来说,TRANSFORM 后的aggfunction,对应的是透视表的值区域,SELECT的statement对应的是透视表的行字段(透视表的行字段肯定是去重归类的),而PIVOT则是对应透视表的列字段。因此TRANSFROM的语法汉化后如下:TRANSFROM 聚合值字段SELECT 行字段 FROM 数据源 GROUP BY 分组行字段PIVOT 分组列字段 ……说好的SELECT指定行字段,怎么又多出来FROM 和 GROUP BY子句了呢?这是因为SELECT是指SELECT语句,而不是SELECT子句SELECT 行字段 FROM 数据源 GROUP BY 分组行字段将这句作为一个整体来看,是不是一条我们所熟悉的SELECT查询语句?摊手。FROM子句指定数据源,如果没有数据源,查询也就成了无水之源。GROUP BY子句对数据源指定的行字段进行去重分类。前面说过,交叉表是按行列两个方向分类汇总的二维表,倘若没有GROUP BY子句对行字段进行去重分类,之后的汇总也就成了问题。最后由SELECT子句指定交叉表显示的行字段。 因此,标红色的部分,作为一条完整SELECT语句,指定了数据源以及交叉表的行字段。 ……照例举个例子。如下图所示,是一份'成绩表’。
我们希望通过SQL的交叉表查询方法,实现查询结果如下:
语句如下:TRANSFORM SUM(成绩) SELECT 姓名 FROM [成绩表$] GROUP BY 姓名 PIVOT 学科 标红色的SELECT语句,指定了交叉表的数据源(成绩表)及分类汇总的行字段,也就是姓名。
有朋友说,数据源并不存在'英语'这门学科呀!是的,但这并不妨碍我们无中生有没事找事啊。无赖脸。事实上,在实际工作中也是有此类需要的。比如,汇总展示全年的数据,你不能因为12月份没有数据,就不体现12月份的数据……。在TRANSFORM语句的关键字PIVOT后面,有一个可选的IN语句:PIVOT pivotfield [IN (value1[, value2[, ...]])],它可以对列字段进行筛选删除或增加。使用以下语句,我们即可实现在列字段中新增字段名'英语’。TRANSFORM SUM(成绩) SELECT 姓名 FROM [成绩表$] GROUP BY 姓名 PIVOT 学科 IN(语文,数学,英语) 而如果我们需要删除'数学’,只保留'语文’和'英语’两个字段,则可以使用:IN(语文,英语) 需要说明的是,这里的IN运算符只支持常量,不支持子查询。它默认它的参数均为常量,因此IN(语文,数学,英语),可以写成也可以不写成IN('语文’,’数学’,’英语’)。此外,IN运算符还可以决定列字段的排放顺序,例如IN(语文,数学),在结果表中,'语文'字段在前,'数学'字段在后;而IN(数学,语文),在结果表中,则是'数学'在前,'语文'在后。
4.
如果我们需要在列字段中增加'总分’数据,就像透视表那样有一列汇总列,该如何处理呢?在SELECT子句指定显示的行字段中,使用聚合函数SUM,新增一列求和成绩的记录,并用关键字AS赋以别名'总分’即可。语句如下:TRANSFORM SUM(成绩) SELECT 姓名,SUM(成绩) AS 总分 FROM [成绩表$] GROUP BY 姓名 PIVOT 学科查询结果如下:
如果我们不但需要总分,还需要平均分呢?大同小异,语句如下:TRANSFORM SUM(成绩) SELECT 姓名,SUM(成绩) AS 总分,AVG(成绩) AS 平均分 FROM [成绩表$] GROUP BY 姓名 PIVOT 学科查询结果如下:
稍加观察,不难发现,上述图片所示的查询结果,不过是把交叉表的值,由'成绩’字段改成了'姓名’字段,因此我们可以将查询语句写成如下:TRANSFORM 姓名 SELECT 姓名 FROM [成绩表$] GROUP BY 姓名 PIVOT 学科但语句运行后的结果和我们最终的目标稍有不同:
交叉表的行字段,也就是'姓名’字段,是我们所不需要显示的,我们需要显示的是'班级’。不知你是否有留意到,前面描述TRANSFORM汉化语法的时候,我们有重点字体加粗标注过,SELECT语句中的GROUP BY子句决定了交叉表实际上的分组行字段,而SELECT子句则决定了交叉表显示的行字段——因此我们可以将代码修改如下:TRANSFORM 姓名 SELECT NULL AS 班级 FROM [成绩表$] GROUP BY 姓名 PIVOT 学科使用一列NULL值作为交叉表显示的行标题记录,并使用关键字AS赋以别名'班级’,即可得到我们所需要的查询结果。
6.
最后,小贴士…… 1),TRANSFORM语句支持WHERE子句,但不支持HAVING子句。 例如我们只需要查询各科成绩大于等于60分的交叉表数据,语句如下:TRANSFORM SUM(成绩) SELECT 姓名 FROM [成绩表$] WHERE 成绩>=60 GROUP BY 姓名 PIVOT 学科查询结果如下,只体现了及格学员的成绩: