注重在以上语句中,子查询充当SELECT列表中的一个复杂表达式,并且它还包含一个聚集函数SUM(),这里我们可以看到使用它的灵活性。
子查询的另一种使用场景即派生表,实际你可以将它看作一个逻辑表。
考虑以下的例子:
| SELECT ; C.customerid, ; P.prodUCt_count AS p_count; FROM Customers C, ; (SELECT c2.customerid, ; COUNT(DISTINCT D.productID) AS p_count ; FROM Customers C2 ; INNER JOIN Orders O ; ON C2.customerid = O.customerid ; INNER JOIN OrderDetails D ; ON O.orderid = D.orderid ; GROUP BY c2.customerid) AS P ; WHERE C.customerID = p.customerID ; AND P.p_count >= ; (SELECT (COUNT(*)*.50) FROM Products) ; ORDER BY p.product_count DESC |
这个SELECT语句返回客户ID、所有购买了50%产品的客户,以及它们所购买的产品数量。
观察以上的语句,你可以发现派生表有一个名为“P”的别名,这与普通字段别名的语法一样――都必须用AS子句来表达。而且这个子查询很复杂(在本例中,它关联了两个表),这个派生表还可以作为WHERE子句的一个条件或者将它放在ORDER BY子句中。
与投影不同,派生表能返回多个字段以及多条记录,但它不能相互关联。另外,所有的子查询都会在主句中的SELECT执行之前运行。
子查询还可以充当UPDATE语句中的SET列表。但SET子句只答应使用一个子查询,并且当SET子句使用子查询后,那WHERE子句中就不答应再使用子查询了。
更好的关联支持
新版本中的UPDATE语句和DELETE语句支持关联。这样,一条语句可以引用不同的表,如下所示:
| DELETE products ; FROM mfg ; WHERE mfg.productID = products.productID; AND mfg.discontinued = .t. |
这个DELETE语句删除mfg表中所有不再生产的产品。
另一个关联UPDATE语句示例如下:
| UPDATE products ; SET unitprice = mfg.msrp *.90 ; FROM mfg ; WHERE mfg.productID = products.productID |
这条UPDATE语句将零售产品的价格打了九折。可能你会问:它支持子查询吗?当然支持。但使用的时候要格外小心。因为假如子查询没有返回任何记录,那将会返回一个值为NULL的空记录。而这恰恰不是你所希望得到的结果。如下所示:
| UPDATE products ; SET unitprice = ; (SELECT ( msrp *.90 ) ; FROM mfg ; WHERE mfg.productID = products.productID) |
这条UPDATE语句的作用与上条基本相似,但假如子查询中的产品没有找到的话,那unitprice将被置为NULL。
视图与查询设计器
尽管新版本增强了子查询功能,但不幸的是在视图与查询设计器中并不支持这种增强功能。并且由于SQL中的IN子句中的元素数目取消了硬编码的限制,但视图与查询设计器中并不知道,因此假如你使用设计器,那IN子句还是只支持24个元素。
增强的UNION操作符
由于联结的数量没有了硬编码的限制,你可以在INSERT INTO子句的结果集中使用UNION。也可以在使用UNION的同时使用ORDER BY子句。
性能
不管你是访问远程数据还是依靠于它强大的本地数据库引擎,Visual FoxPro始终将性能考虑在第一位。Visual FoxPro 9进一步地增强了数据引擎的功能。
二进制索引
这种新型的索引使用方法如下:
INDEX ON DELETED() TAG DELETED BINARY
这种索引能与任何非空的逻辑表达式一起使用。除此之外,FOR表达式、ASCENDING、DESCENDING、UNIQUE或CANDIDATE要害字不能与它一起使用。
二进制索引并不支持SET ORDER TO命令,而且INDEX ON命令会将当前的order设为0。但你可在Seek语句中使用二进制索引。
二进制索引最大的优势在于它的索引文件大小。以一个包含800万条记录的表为
