不等连接的标量子查询改写
前面的例子中,标量子询查中都是等值的关联条件,能直接改为LEFT JOIN 或者汇总后再用LEFT JOIN,但遇到不等连接怎么办呢?
SELECT a.licenceid,
a.data_source,
a.street,
(SELECT MIN(contdata)
FROM ct
WHERE ct.licenceid = a.licenceid
AND ct.data_source = a.data_source
AND trunc(contdate) >= a.opendaledate) AS mincontdata,
(SELECT MIN(buydate)
FROM ct
WHERE ct.licenceid = a.licenceid
AND ct.data_source = a.data_source
AND trunc(buydate) >= a.opendaledate) AS minbuydate
FROM a;
要想把两个量合并,必须要先与a表关联,这样才能在取最值前过滤
SELECT a.rowid AS rid,
MIN(CASE WHEN trunc(ct.contdate) >= a.opendaledate) THEN
ct.contdate END)AS mincontdate,
MIN(CASE WHEN trunc(ct.buydate) >= a.opendaledate) THEN
ct.buydate END)AS minbuydate
FROM ct
INNER JOIN a ON(ct.licenceid = a.licenceid
AND ct.data_source = a.data_source)
GROUP BY a.rowid
到此标量部分搞定,再左联就可以了
WITH ct2 AS(
SELECT a.rowid AS rid,
MIN(CASE WHEN trunc(ct.contdate) >= a.opendaledate) THEN
ct.contdate END)AS mincontdate,
MIN(CASE WHEN trunc(ct.buydate) >= a.opendaledate) THEN
ct.buydate END)AS minbuydate
FROM ct
INNER JOIN a ON(ct.licenceid = a.licenceid
AND ct.data_source = a.data_source)
GROUP BY a.rowid)
SELECT a.licenceid,
a.data_source,
a.street,
ct2.mincontdate AS mincontdate,
ct2.minbuydate AS minbuydate
FROM a
LEFT JOIN ct2 ON(ct2.rid = a.rowid);
选自《Oracle 查询优化改写技巧与案例》 有教无类 落落 著