Office中国论坛/Access中国论坛

标题: 趣谈子查询 [打印本页]

作者: todaynew    时间: 2009-1-15 20:27
标题: 趣谈子查询


  最近一周以来对SQl中的子查询突感兴趣。起因是版友Punter同志让我提供“对若干条数据记录作过程分析的简易方法”,因未成提供具体实例,加之在下此前却也不懂,便敷衍搪塞了Punter同志。细细想来,Punter同志所问却也是在下常常困惑的问题。我们知道如果用Excel做记录间的运算十分简单,然而对于Access来说表的记录间是相互独立的,所谓鸡犬相闻,老死难以往来。可是记录之间客观上是有关系的,如果缺乏了记录间的分析手段,Access的运用便也就受到了很大限制。

  带着这个疑问,最近一直在观察版面相关的内容,也就逐渐发现用SQl的子查询可以部分解决问题。于是便跟踪了数个问题,也尝试着解答一番,也就颇有心得和收获。于是乎想与诸位初学者交流交流,把这个看似有点玄乎的子查询掰开来演绎一番,也算是在新春即将到来之际与诸君谈笑一二。

  我们先假设一个情景,你有一个严苛的老板(不妨假设她还是一个美女),她最近的生意因为金融风暴的影响每况愈下,正琢磨着裁员。而你不希望被裁掉,总想瞅准机会表现表现,于是你听人说Access可以救你的命,便恶补Access,不几日也就能在老板经过你身边的时候假模假样的写点小小的程序。老板一看,这小伙子年轻英俊,还懂点编程,看来需要留用,便交给你编写一个收发存的程序。

  等你真的上手,发现不是那么容易了,那个库存的问题实在麻烦的不得了。这时,你就有必要看本帖了!

  在此之前,我们如下列图示先做一些准备工作(见二楼的前几个图片),根据这些东西,你要完成你的工作。

        
  当我告诉你能够算出每日从期初以来的累计收料量和每日从期初以来的累计发料量,你当然会认为已经接近解决库存问题了。因为你知道用期初库存加上每日的累计收料量减去每日的累计发料量便是本日的库存了。如何计算这两个累计数呢?告诉你,是下面这个叫做查询1的东西。

SELECT a.日期, a.物资ID, a.名称, a.期初, a.收料, (select sum(b.收料) from 基础查询 as b where b.物资ID=a.物资ID and b.日期<=a.日期) AS 收料累计, a.发料, (select sum(b.发料) from 基础查询 as b where b.物资ID=a.物资ID and b.日期<=a.日期) AS 发料累计
FROM 基础查询 AS a;

       做完这个查询,你发现它还有许多用处。比如你想要做一个本月发生额与累计发生额的统计报表,原来也可以使用它。可是你觉得这个查询毕竟还是没有解决你的问题。没关系,告诉你计算库存的真正查询是什么。这就是我向你隆重推荐的查询2。

SELECT a.日期, a.物资ID, a.名称, a.期初, a.收料, a.发料, (select sum(b.期初+b.收料-b.发料) from 基础查询 as b where b.物资ID=a.物资ID and b.日期<=a.日期) AS 期末
FROM 基础查询 AS a;

       你觉得完全成功了,你便打算给美女老板看看你的开发成果。你昂着头挺着胸面见了老板,展示了你的科研成果。可是老板看了后,却把你大骂一通,说你搞的东西每条记录收发存都不平衡。你灰溜溜的退出来,恶狠狠的骂道:“老子就是娶个瞎子也不要你这个恶婆娘!”可是骂归骂,饭碗是人家给的,在人屋檐下岂能不低头。算了,我再告诉你一个查询3,帮你解决这个问题。

SELECT a.日期, a.物资ID, a.名称, 期末+发料-收料 AS 期初, a.收料, a.发料, (select sum(b.期初+b.收料-b.发料) from 基础查询 as b where b.物资ID=a.物资ID and b.日期<=a.日期) AS 期末
FROM 基础查询 AS a;

       你总算松了口气,便又兴冲冲的推开老板的门。老板这会看来心情不错,正对着小镜子抹着口红,扑着香粉。你小心翼翼的打开你的程序,老板看了看,揪了一把你的脸说道:“这还不错。不过给每个记录加个序号会更爽。”你不敢说不会,便又退回来,没关系你继续看看下面这个查询4。

SELECT (select count(*) from 基础查询 as b where b.物资ID=a.物资ID and b.日期<=a.日期) AS 序号, a.日期, a.物资ID, a.名称, 期末+发料-收料 AS 期初, a.收料, a.发料, (select sum(b.期初+b.收料-b.发料) from 基础查询 as b where b.物资ID=a.物资ID and b.日期<=a.日期) AS 期末
FROM 基础查询 AS a;

       做完这些,你又想了想,这次不能让她再挑出毛病了。于是你就琢磨搞点趋势分析的内容在里面,让这美女对你刮目相看。好了,给你准备了一个查询5,绝对能唬弄唬弄她。

SELECT a.物资ID, a.名称, a.日期, a.日期-(select last(b.日期) as 日期1 from 基础查询2 as b where b.物资ID=a.物资ID and b.日期<a.日期) AS 收料周期, a.收料, a.收料-(select last(b.收料) as 收料1 from 基础查询2 as b where b.物资ID=a.物资ID and b.日期<a.日期) AS 收料变动, Round(收料变动/a.收料,4) AS 变动幅度
FROM 基础查询2 AS a;

     等你再一次进入老板的房间时,等待你的是香吻和共进晚餐的邀请。你的饭碗一定保住了,或许你还能得到更多的东西,呵呵。



[attach]34576[/attach]

[ 本帖最后由 todaynew 于 2009-1-16 11:03 编辑 ]
作者: sheandme0    时间: 2009-1-15 20:33
沙发啊 !!!
作者: baijun    时间: 2009-1-15 21:34
标题: 好贴,
好贴好贴好贴啊......顶啊顶啊,学习中
作者: fnsmydyang    时间: 2009-1-15 22:41
真的好好的学习一下,谢谢分享
作者: Henry D. Sy    时间: 2009-1-16 07:10
todaynew老兄,真是个人才。
文采这么好,学编程是个浪费。
作者: todaynew    时间: 2009-1-16 08:19
楼上的版主及诸君:谢谢同志们鼓励。[:50] [:50] [:50]
作者: asklove    时间: 2009-1-16 08:32
[:15] [:15] [:15]
作者: todaynew    时间: 2009-1-16 11:03
原帖由 asklove 于 2009-1-16 08:32 发表
[:15] [:15] [:15]


[:24] [:24] [:24]
作者: boy1    时间: 2009-1-16 11:09
标题: 先收藏,学习学习。
先收藏,学习学习。
作者: changweiren    时间: 2009-1-16 21:30
[:50] [:50] [:50]
作者: yeguiren6076    时间: 2009-1-18 14:13
真有这么好吗?是示例吗?
作者: summeryan    时间: 2009-2-17 15:27
强,正困惑中,要好好学习下!
作者: wang1950317    时间: 2009-2-17 16:24
为楼主鼓掌,祝愿楼主“还能得到更多的东西”!
作者: koutx    时间: 2009-2-17 16:45
精彩收藏,中国第一篇含有编程内容的小小说。
作者: todaynew    时间: 2009-2-17 19:33
精彩收藏,中国第一篇含有编程内容的小小说。
koutx 发表于 2009-2-17 16:45



作者: luhao    时间: 2009-3-11 00:04
字太多了,先下载
作者: huangxiuwen    时间: 2009-3-11 00:11
学习
作者: wanglhc    时间: 2009-3-12 11:53
好贴,先收下再学习!
作者: wwjing    时间: 2009-3-18 17:52
学习学习!
作者: wen123456    时间: 2009-5-16 19:41
好好学习下
作者: jetone    时间: 2009-5-19 17:35
听君一席话,胜读十年书
作者: 鱼儿游游    时间: 2009-11-2 02:25

作者: kelinkeli104    时间: 2009-11-2 12:09
谢谢楼主的分享。
作者: winkeyyou    时间: 2009-11-4 13:22
参考一下
作者: youqiang    时间: 2010-3-6 22:29
todaynew:你好!
  我是一个新手,你给的例子实在太好了,学生我受益匪浅,我还想请教一下:
SELECT a.日期, a.物资ID, a.名称, a.期初, a.收料, a.发料, (select sum(b.期初+b.收料-b.发料) from 基础查询 as b where b.物资ID=a.物资ID and b.日期<=a.日期) AS 期末
FROM 基础查询 AS a;
  这里的“sum(b.期初+b.收料-b.发料)”中的“b“是怎么出现的?
  学生我在这里拜谢了!
作者: todaynew    时间: 2010-3-7 06:21
todaynew:你好!
  我是一个新手,你给的例子实在太好了,学生我受益匪浅,我还想请教一下:
SELECT a.日期, a.物资ID, a.名称, a.期初, a.收料, a.发料, (select sum(b.期初+b.收料-b.发料) from 基础查询 as ...
youqiang 发表于 2010-3-6 22:29

from 基础查询 as b,说明b为基础查询的别名。所以 b.期初 等价于 基础查询.期初。采用别名的目的,除了简化程序外,还可以在子查询中区别同一表的两处以上的引用。
作者: hgxsyhb    时间: 2010-3-15 19:39
xuexi学习学习
作者: lovehere    时间: 2010-3-18 17:30
先收藏,在慢慢学习
作者: youchytan    时间: 2010-3-20 10:01
伙计,你该改行做写手了!
作者: yanghua1900363    时间: 2011-9-27 16:02
谢谢分享!这个问题正困惑着我呢!
作者: tzh16000    时间: 2011-9-29 15:23
在我还不懂得用代码前,很多功能都是用查询来实现的,其实查询的功能很强大
作者: xyhecho2002    时间: 2012-1-21 10:57
学习
作者: 风中漫步    时间: 2012-1-21 13:04
收藏,谢谢分享
作者: cumtclmk123    时间: 2015-3-1 09:39
真不错
作者: hyfg    时间: 2015-6-24 18:57
文采加实例,真好
作者: eiyoyo    时间: 2015-7-2 21:42
谢谢分享
作者: 冚友    时间: 2015-7-2 23:00
学习
作者: a30088    时间: 2015-7-16 18:54
多条数据时,运行太慢,不可用啊
作者: a157838566    时间: 2015-7-28 14:51
fasdfadsf
作者: cxtrj    时间: 2016-4-10 09:25
收藏了。
作者: cxtrj    时间: 2016-4-10 09:33
学习学习。
作者: access新新新手    时间: 2016-4-10 09:59
谢谢分享
作者: xlb004    时间: 2016-5-12 20:02
111111111111111111111111111111
作者: wenghuangwei    时间: 2016-11-26 02:44
我看完了,下了再说!




欢迎光临 Office中国论坛/Access中国论坛 (http://www.office-cn.net/) Powered by Discuz! X3.3