交叉表查询中的累计

原创 2010年01月10日 22:49:00

交叉表查询无疑有使用中可以很方便的进行数据的分析处理。你可以通过向导来生成(在向导中你可以选择是否生成行合计)或者直接按照这个ACCESS特有JET-SQL语法来写这个SQL语句。

TRANSFORM合计函数
    selectstatement
    TRANSFORM aggfunction
selectstatement
PIVOT pivotfield [IN (value1[, value2[, ...]])]


比如现有表 table3, 数据如下
+----+---------+-------+--------+------+-------------+
|id  |sName    |sClass |Course  |Score |homeworkScore|
+----+---------+-------+--------+------+-------------+
|1   |AAA      |3      |语文    |50    |76           |
|2   |AAA      |3      |数学    |83    |77           |
|3   |AAA      |3      |英语    |65    |60           |
|4   |BBB      |3      |语文    |86    |72           |
|5   |BBB      |3      |数学    |95    |57           |
.......

|31  |LL       |5      |语文    |80    |75           |
|32  |LL       |5      |数学    |95    |70           |
+----+---------+-------+--------+------+-------------+
可以用向导得到一个每人的成绩表如下
+--------+-------+---------------+-------+-------+-------+
|sName   |sClass |Total Of Score |数学   |英语   |语文   |
+--------+-------+---------------+-------+-------+-------+
|AAA     |3      |198            |83     |65     |50     |
|BBB     |3      |239            |95     |58     |86     |
......

|LL      |5      |175            |95     |       |80     |
+--------+-------+---------------+-------+-------+-------+


它对应的SQL语句如下:
TRANSFORM Sum(Table3.Score) AS ScoreOfSum
SELECT Table3.sName, Table3.sClass, Sum(Table3.Score) AS [Total Of Score]
FROM Table3
GROUP BY Table3.sName, Table3.sClass
PIVOT Table3.Course;

关于这个SQL语句的说明,你可以自已查阅一下ACCESS自带的帮助手册中的详细说明。
如果你想控制科目的显示顺序,可以试一下这个语法的作用。PIVOT pivotfield [IN (value1[, value2[, ...]])]

以上是交叉表查询的常见用法。美中不足,这个由向导生成的查询虽然有了行合计,但没有列合计。由于TRANSFORM 自身功能的限制无法直接生成列合计运算(我们这里所说的合计运算包括平均/最大/最小等,以下均不再说明)。但我们可以通过UNION联合来实现。

思路:直接在table3的数据中追加上合计行然后再进行交叉。

比如如果table3的数据能形成如下记录
+----+---------+-------+--------+------+-------------+
|id  |sName    |sClass |Course  |Score |homeworkScore|
+----+---------+-------+--------+------+-------------+
|1   |AAA      |3      |语文    |50    |76           |
|2   |AAA      |3      |数学    |83    |77           |
|3   |AAA      |3      |英语    |65    |60           |
...
|31  |LL       |5      |语文    |80    |75           |
|32  |LL       |5      |数学    |95    |70           |
|    |Average  |       |英语    |86    |            |
|    |Average  |       |数学    |77    |            |
|    |Average  |       |英语    |99    |            |
+----+---------+-------+--------+------+-------------+


这样我们就可以利用 TRANSFORM 来实现了。

1. 生成合计,你可以通过向导或自己生成这个合计的查询
select course,avg(score)
from table3
group by course


+-------+-----------------+
|course |Expr1001         |  
+-------+-----------------+
|数学   |81.3636363636364 |
|英语   |65.4             |
|语文   |77.0909090909091 |
+-------+-----------------+

2. 利用UNION生成交叉表查询的数据源。(这里我们用了UNION ALL,关于UNION的语法说明请自行查阅帮助,同样我们利用 'Total' as sName,null as sClass 生成了两个常数列以保证UNION的两个集合的列数相匹配。)

本帖隐藏的内容需要回复才可以浏览

select sName,sClass,Course,Score
from Table3
union all
select 'Total' as sName,null as sClass,course,avg(score)
from table3
group by course



+-------+--------+-------+-----+
|sName  |sClass  |Course |Score|
+-------+--------+-------+-----+
|AAA    |3       |数学   |83   |
|AAA    |3       |英语   |65   |
.....
|LL     |5       |数学   |95   |
|Total  |        |数学   |81.36|
|Total  |        |英语   |65.4 |
|Total  |        |语文   |77.09|
+-------+--------+-------+-----+

3. 把这个查询代入到一开的那个交叉查询中,替代原来的table3.
把把所有的table3. 换成 t. 如下

TRANSFORM Sum(t.Score) AS ScoreOfSum
SELECT t.sName, t.sClass, Sum(t.Score) AS [Total Of Score]
FROM Table3
GROUP BY t.sName, t.sClass
PIVOT t.Course;


然后再把 from table3 变成

本帖隐藏的内容需要回复才可以浏览

TRANSFORM Sum(t.Score) AS ScoreOfSum
SELECT t.sName, t.sClass, Sum(t.Score) AS [Total Of Score]
FROM (select sName,sClass,Course,Score
    from Table3
    union all
    select 'Total' as sName,null as sClass,course,avg(score)
    from table3
    group by course) t
GROUP BY t.sName, t.sClass
PIVOT t.Course;



结果如下
+--------+------+------+-----+-----+-----+
|sName   |sClass|Total |数学 |英语 |语文 |
+--------+------+------+-----+-----+-----+
|AAA     |3     |198   |83   |65   |50   |
|BBB     |3     |239   |95   |58   |86   |
.......

|JJJJ    |5     |220   |97   |61   |62   |
|LL      |5     |175   |95   |     |80   |
|Total   |      |223.85|81.36|65.4 |77.09|
+--------+------+------+-----+-----+-----+



如果我们想再加上每个班的小计
那么就再union上每个班的合计平均值

本帖隐藏的内容需要回复才可以浏览

select 'subtotal' as sName,sClass,course,avg(score)
from table3
group by course,sClass

这样改为
TRANSFORM Sum(t.Score) AS ScoreOfSum
SELECT t.sName, t.sClass, Sum(t.Score) AS [Total Of Score]
FROM (select sName,sClass,Course,Score
    from Table3
    union all
    select 'subtotal' as sName,sClass,course,avg(score)
    from table3
    group by course,sClass
    union all
    select 'Total' as sName,null as sClass,course,avg(score)
    from table3
    group by course
) t
GROUP BY t.sName, t.sClass,(t.sClass='subtotal'),(t.sClass='Total')
order by (t.sClass='Total') desc,(t.sClass='subtotal') desc,sClass
PIVOT t.Course


上面用了 order by (t.sClass='Total') desc,(t.sClass='subtotal') desc,sClass 来控制排序,以把subtotal, total 放在最后。
+----------+--------+---------+------+------+------+
|sName     |sClass  |Total Of |数学  |英语  |语文  |
+----------+--------+---------+------+------+------+
|AAA       |3       |198      |83    |65    |50    |
|BBB       |3       |239      |95    |58    |86    |
....

|subtotal  |3       |222.4    |81    |67.2  |74.2  |
......

|LL        |5       |175      |95    |      |80    |
|subtotal  |5       |228      |96    |61    |71    |
|Total     |        |223.8545 |81.363|65.4  |77.090|
+----------+--------+---------+------+------+------+


结束语:
显然通过灵活的SQL语句设计我们可以实现多种需要有VBA程序中实现功能。在实际运用中我们需要在各种方案之间来平衡以找到最佳的应用。有时候用程序的效率比较好,有些时候用查询的比较方便,有些时候甚至跳出ACCESS用EXCEL可能更容易。

交叉表、行列转换和交叉查询经典

交叉表、行列转换和交叉查询经典 一、什么是交叉表 “交叉表”对象是一个网格,用来根据...
  • cngkqy
  • cngkqy
  • 2007年12月05日 16:01
  • 15078

C#动态交叉表查询

  • 2013年07月31日 21:27
  • 309KB
  • 下载

mysql 查询拓展 触发器 交叉表 存储过程

SHOW TRIGGERS; DROP TRIGGER insertUser DROP TRIGGER deleteUser; DROP TRIGGER updateUser;CREATE TRIGG...

不定长字段交叉表查询

  • 2010年07月09日 18:51
  • 1KB
  • 下载

4.mysql数据库创建,表创建模等模板脚本,mysql_SQL99标准的连接查询(内连接,外连接,满外连接,交叉连接)

mysql数据库创建,表创建模等模板脚本 -- 用root用户登录系统,执行脚本   -- 创建数据库 create database mydb61 character set...

多表连接查询(内,外,交叉连接)

多表连接查询(内,外,交叉连接) 连接查询实际上是通过各个表之间共同列的关联性来查询数据的,它是关系数据库查询最主要的特征. select 表1.字段名1,表2.字段名2,...  fr...

交叉表查询(普通行列转换)

问题:假设有张学生成绩表(tb)如下: 姓名 课程 分数 张三 语文 74 张三 数学 83 张三 物理 93 李四 语文 74 李四 数学 84 李四 物理 94 想...

SQL连表查询:内连接、左联接、右连接、全连接、交叉连接讲解

本文为大家讲解的是sql的连表查询:SQL连接可以分为内连接、左联接、右连接、全连接、交叉连接的用法,mysql,sql server,access等关系型数据库语法其实都差不多,本文是以sql se...
  • hhaeals
  • hhaeals
  • 2015年01月11日 12:08
  • 272
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:交叉表查询中的累计
举报原因:
原因补充:

(最多只允许输入30个字)