having参数一般是与group by参数使用,是告诉SQL将那些符合过滤条件的组别含入查询结果中。不过在条件式中不能包含一个子查询。但如果having不与group by一同使用时,它就与where参数类似。但两者有两个区别导致having是不会快过where参数的。
select的条件过滤的先后顺序是这样的(我是根据经验而猜得,不知对否):先对join中的on表达式进行过滤,再到where,中间结果出来后再用having进行过滤,最后才把结果显示出来。所以说having是对select结果的最后一次过滤。它与where的分别就是where能够事先把不要的数据过滤掉,这样select里头就不用处理那么多的数据。但有些数据事先不知道要不要过滤,要根据结果才能确定,这时才用having这个事后诸葛亮。但因为having是事后诸葛亮,对结果产生再进行条件筛选的,所以不能使用Rushmore,其效率可想而知有多高了。
这里兴修例子来比较一下on、where、having的不同之处
表recdbf内容如下: 还有一个tempyf的辅助表,记录12个月
| 日期 | 性质 | yf |
| 2000年7月3日 | 特大 | 1 |
| 2000年7月9日 | 特大 | 2 |
| 2000年9月3日 | 特大 | 3 |
| 1999年3月2日 | 一般 | 4 |
| 1999年3月4日 | 一般 | 5 |
| 2000年1月3日 | 一般 | 6 |
| 2000年2月1日 | 一般 | td> |
| 2000年2月3日 | 一般 | 8 |
| 2000年3月4日 | 一般 | 9 |
| 2000年8月7日 | 一般 | 10 |
| 2000年11月2日 | 一般 | 11 |
| 1999年2月3日 | 重大 | 12 |
| 2000年2月3日 | 重大 | |
| 2000年5月2日 | 重大 | |
| 2000年8月9日 | 重大 |
on的命令如下
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;
GROUP BY tempyf.yf
其中yy=2000,表示统计2000年的数据
用where的命令如下:
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.日期);
GROUP BY tempyf.yf ;
where YEAR(日期) = ?yy &&注意,条件从on移到这里来了
用having的命令如下:
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.日期);
GROUP BY tempyf.yf ;
having YEAR(日期) = ?yy &&注意,条件从on移到这里来了
on的结果如下,这是正确的
| YF | 一般 | 重大 | 特大 |
| 1 | 1 | 0 | 0 |
| 2 | 2 | 1 | 0 |
| 3 | 1 | 0 | 0 |
| 4 | 0 | 0 | 0 |
| 5 | 0 | 1 | 0 |
| 6 | 0 | 0 | 0 |
| 7 | 0 | 0 | 2 |
| 8 | 1 | 1 | 0 |
| 9 | 0 | 0 | 1 |
| 10 | 0 | 0 | 0 |
| 11 | 1 | 0 | 0 |
| 12 | 0 | 0 | 0 |
用where的结果如下:
| YF | 一般 | 重大 | 特大 |
| 1 | 1 | 0 | 0 |
| 2 | 2 | 1 | 0 |
| 3 | 1 | 0 | 0 |
| 5 | 0 | 1 | 0 |
| 7 | 0 | 0 | 2 |
| 8 | 1 | 1 | 0 |
用having的结果如下:
| YF | 一般 | 重大 | 特大 |
| 1 | 1 | 0 | 0 |
| 2 | 2 | 2 | 0 |
| 5 | 0 | 1 | 0 |
| 7 | 0 | 0 | 2 |
| 8 | 1 | 1 | 0 |
| 9 | 0 | 0 | 1 |
| 11 | 1 | 0 | 0 |
各位看到有什么不同吗?
上一页 下一页






