SQL查询和优化(十一)

不等连接的标量子查询改写

前面的例子中,标量子询查中都是等值的关联条件,能直接改为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 查询优化改写技巧与案例》 有教无类 落落 著

猜你喜欢

转载自blog.csdn.net/every__day/article/details/77128617