ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 3668|回复: 9

[分享] access交叉表查询中的累计

[复制链接]

TA的精华主题

TA的得分主题

发表于 2011-6-16 00:04 | 显示全部楼层 |阅读模式
交叉表查询无疑有使用中可以很方便的进行数据的分析处理。你可以通过向导来生成(在向导中你可以选择是否生成行合计)或者直接按照这个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可能更容易。

TA的精华主题

TA的得分主题

发表于 2011-6-17 07:05 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册

〖Excel Home友情提示〗

   

很遗憾通知楼上朋友,您的帖子在24小时之内没有任何回复!

通常情况下,本论坛发布的主题帖会在8小时被回复或处理。您的帖子在24小时之内未被回复,其中的原因可能是

1、问题表述不清、模棱两可,难以理解,帮助者被搞晕了,夺帖而出;
2、没有上传必要的附件,或附件被遗忘在某个角落;
3、发帖提问时,语气带棱角、带挑衅,不幸被列入不受欢迎的帖子;
4、所提问题不成立,或提不合理的要求,乐于助人者使出“走为上”之计;
5、话题较偏、较冷或者发布到了不合适的版块,暂时无人问津,顾影自怜。


为了提高您的问题解决效率,我们推荐您阅读以下文章:
* 如何发表新话题和上传附件:http://club.excelhome.net/thread-45649-1-1.html
* 发帖的技巧:http://club.excelhome.net/thread-176339-1-1.html
* EH技术论坛的最佳学习方法:http://club.excelhome.net/thread-117862-1-1.html

TA的精华主题

TA的得分主题

发表于 2011-6-22 10:29 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2011-8-22 09:02 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2011-8-22 09:13 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
能否用在EXCEL上

TA的精华主题

TA的得分主题

 楼主| 发表于 2011-8-25 16:26 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2012-6-12 16:32 来自手机 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2012-7-31 16:38 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2012-8-21 21:53 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2012-8-30 05:53 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
还没看懂 慢慢学习
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2025-1-8 12:55 , Processed in 0.030255 second(s), 8 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表