这里还有一个更绝的例子:
表recdbf
〖性质〗分一般、重大、特大;
〖日期〗
要统计出某年的12个月内每个月每种性质的记录各有多少,若该月没有记录就为零。
结果:
月份 一般 重大 特大
1 0 1 3
2 2 12 3
......
12 3 0 5
这跟上面那个例子有点不同,上例只是按表中科室来分类,而这里就不同,因为不是每个月都有案件的,但在报表里没有案件的月也要占一行。所以这里要建立一个辅助表:tempyf( yf N(2)),内有十二个记录,值为1至12,代表1-12月。
我先是老规则:
sele mont(日期),iif(性质='一般',1,0) as 一般,iif(性质='重大',1,0) as 重大,iif(性质='特大',1,0) as 特大 ;
from recdbf ;
where year(日期)=?年份 ;
into curs temp1
再用tempyf左联接临时表temp1,根据tempyf.yf分组统计。
但一看,结果好象不对,没有记录的月份不在结果当中,而且这两条select好象可以合而为一。这时,狐性大发,立决心要搞定它。
在看MSDN Help时,灵光一闪:把过滤条件从where移到联接条件中,直接使用sum命令统计iif的结果!几经波折,终于写出下面的命令
SELECT tempyf.*,;
SUM(IIF(ISNULL(recdbf.日期).OR.AT("一般",recdbf.性质)=0,0,1)) AS 一般,;
SUM(IIF(ISNULL(recdbf.日期).OR.AT("重大",recdbf.性质)=0,0,1)) AS 重大,;
SUM(IIF(ISNULL(recdbf.日期).OR.AT("特大",recdbf.性质)=0,0,1)) AS 特大;
FROM tempyf LEFT OUTER JOIN recdbf ;
ON tempyf.yf = MONTH(recdbf.日期).AND.YEAR(日期) = ?yy; &&注意这里,on后面是可以加上其它条件的
GROUP BY tempyf.yf
结果完成符合要求!
这个yy是指具体那一年,如果不指定的话,那就是把表中所有的记录算在一起。而且如果要指定具体那一年的话,那这个YEAR(日期) = ?yy的条件是不能放在where或者having里的,不信各位试试。
我最后的感想就是:那个sum命令是可以直接累加iif的结果,而且过滤条件从where移到on后会发生这么大的差别!在where时,是先联接统计后再过滤,结果把那些没有记录的月份也过滤掉了;而在on是先过滤再联接、统计,过滤结果中虽然没有记录的月份也不在其中,但因是左联接,也一样会以null代替,但给iif中的isnull给变成了0!啊,我真是太聪明了!哈哈哈。。。。。
注:其中那个 ON tempyf.yf = MONTH(recdbf.日期) AND YEAR(日期) = ?yy 在视图生成器中是不能直接做的,要用create view as生成(我就做不到,不知各位做不做得到)