对上一步骤产生的虚拟表VT3进行WHERE 条件过滤,只有符合<where_condition>的记录才会输出到虚拟表VT4中。
在当前应用WHERE过滤器时,有两种过滤是不被允许的:
由于数据还没有分组,因此现在还不能在WHERE过滤器中使用where_condition= MIN(col)这类对统计的过滤。
由于没有进行列的选取操作,因此在SELECT中使用列的别名也是不被允许的,如SELECT city as c FROM t WHERE c='ShangHai'是不允许出现的。
首先来看一个在WHERE过滤条件中使用分组过滤查询导致出错的例子。
mysql> SELECT customer_id,COUNT(customer_id)
-> FROM orders
-> WHERE COUNT(customer_id)<2 ;
ERROR 1111 (HY000): Invalid use of group function
可以看到MySQL数据库提示错误地使用了分组函数。接着来看一个列别名使用出错的例子。
mysql> SELECT order_id AS o,customer_id AS c
-> FROM orders
-> WHERE c='163';
ERROR 1054 (42S22): Unknown column 'c' in 'where clause'
因为在当前的步骤中还未进行SELECT选取列名的操作,所以此时的列别名是不被支持的,MySQL数据库抛出了错误,提示未知的列c。
应用WHERE过滤器:WHERE c.city='HangZhou',最后得到的虚拟表VT4如表3-8所示。
此外,在WHERE过滤器中进行的过滤和在ON过滤器中进行的过滤是有所不同的。对于OUTER JOIN中的过滤,在ON过滤器过滤完之后还会添加保留表中被ON条件过滤掉的记录,而WHERE条件中被过滤掉的记录则是永久的过滤。在INNER JOIN中两者是没有差别的,因为没有添加外部行的操作。来看下面这个查询:
SELECT * FROM customers c
LEFT JOIN orders o
ON c.customer_id=o.customer_id AND c.city='HangZhou';
得到的结果如表3-9所示。
表 3-8 虚拟表VT4
c.customer_id c.city o.order_id o.customer_id
163 HangZhou 1 163
163 HangZhou 2 163
baidu HangZhou NULL NULL
TX HangZhou 6 TX
表 3-9 查询结果
c.customer_id c.city o.order_id o.customer_id
163 HangZhou 1 163
163 HangZhou 2 163
9you ShangHai NULL NULL
baidu HangZhou NULL NULL
TX HangZhou 6 TX
对比表3-8和表3-9可以发现,customer_id为9you的记录被添加入后者的查询中。这是因为ON过滤条件虽然过滤掉了city不等于“HangZhou”的记录,但是由于查询是OUTER JOIN,因此会对保留表中被排除的记录进行再次的添加操作。