们的描述,最终按照“先获得子查询的结果,然
后再连接orders和orderstatus表”的顺序工作:
这次,等号左端的字段来自相同的表,从而不必连接orders和orderstatus这两个表了。尽管好
的优化器可能会帮我们做到这一点,但保险起见,一开始就指定这两个字段来自相同的表是更
明智的选择。为优化器保留最大的自由度总是上策。
前面已经看到了,非关联子查询可以变成内嵌视图,且改动不大。下面,我们写出“列出待办订
单”的整个查询语句:
但还有问题,如果最终状态确实是“COMPLETE”,我们就没有必要用子查询检查其最新状态了。
内嵌视图能帮我们找出最后状态,无论它是不是“COMPLETE”。所以我们把查询改为“检查已知
的最新状态”,这个过滤条件非常令人满意:
and (os.ordid, os.statusdate) = (select ordid, max(statusdate)
from orderstatus
group by ordid)
select c.custncom, o.ordid, os.status, os.statusdate
from custcomrs c,
orders o,
orderstatus os,
(select ordid, max(statusdate) laststatusdate
from orderstatus
group by ordid) x
where o.ordid = os.ordid
and not exists (select null
from orderstatus os2
where os2.status = 'COMPLETE'
and os2.ordid = o.ordid)
and os.statusdate = x.laststatusdate
and os.ordid = x.ordid
and o.custid = c.custid
select c.custncom, o.ordid, os.status, os.statusdate
from custcomrs c,
orders o,
orderstatus os,
(select ordid, max(statusdate) laststatusdate
from orderstatus
group by ordid) x
where o.ordid = os.ordid
and os.statusdate = x.laststatusdate
and os.ordid = x.ordid
and os.status != 'COMPLETE'
如果进一步利用OLAP 或SQL 引擎提供的分析功能,还可以避免对orderstatus的重复参照。
不过就此打住,来思考一下我们是如何修改查询的,更重要的是“执行路径(execution path)”