存储子查询结果以在整个查询中重用

时间:2018-02-15 01:48:05

标签: sql database oracle plsql

我试图重复使用子查询的结果,所以我不必通过我的代码继续调用它,我试过了:

WITH MAX_VERSIONS AS (
    SELECT MAX(vernum) AS VERNUM, MAX(defvern) AS DEFVERN
    FROM   llattrdata, DTREE DT 
    WHERE  id = dt.dataid 
            AND defid = 3070056 
            AND attrid = 4
) 
SELECT ID
FROM   llattrdata ad, DTREE DT 
WHERE  ad.id = dt.dataid 
        AND ad.defid = 3070056 
        AND ad.attrid = 4
        AND ad.VERNUM = MAXVERSIONS.VERNUM
        AND ad.DEFVERN = MAXVERSIONS.DEFVERN;

2 个答案:

答案 0 :(得分:2)

您可以使用CROSS JOIN,因为它只返回单行:

;WITH MAX_VERSIONS AS 
(
    SELECT MAX(vernum) AS VERNUM, MIN(defvern) AS DEFVERN
    FROM    llattrdata
            INNER JOIN DTREE DT
                ON id = dt.dataid 
    WHERE   defid = 3070056 
            AND attrid = 4
) 
SELECT  ID
FROM    llattrdata ad
        INNER JOIN DTREE DT 
            ON ad.id = dt.dataid 
        CROSS JOIN MAX_VERSIONS mv
WHERE   defid = 3070056 
        AND attrid = 4
        AND DT.VERNUM = mv.VERNUM    -- must also define which table the column
        AND DT.DEFVERN = mv.DEFVERN; -- is coming from to avoid ambiguity
                                     -- not sure whether it is from [ad] or [DT]

作为替代方案,如果您想在不使用CTE的情况下反复重复使用该值,则可以在变量中声明并存储该值:

DECLARE
    MAX_VERNUM NUMBER(10);
    MAX_DEFVERN  NUMBER(10);

SELECT  MAX(vernum), MIN(defvern)
        INTO MAX_VERNUM, MAX_DEFVERN
FROM    llattrdata
        INNER JOIN DTREE DT
            ON id = dt.dataid 
WHERE   defid = 3070056 
        AND attrid = 4

SELECT  ID
FROM    llattrdata ad
        INNER JOIN DTREE DT 
            ON ad.id = dt.dataid 
WHERE   defid = 3070056 
        AND attrid = 4
        AND VERNUM = MAX_VERNUM
        AND DEFVERN = MAX_DEFVERN;

答案 1 :(得分:0)

为什么在使用窗口函数时会遇到所有这些麻烦:

SELECT ID
FROM (SELECT ID,
             RANK() OVER (PARTITION BY defid, attrid, ORDER BY versum, defvern DESC) as seqnum
      FROM llattrdata ad JOIN
           DTREE DT 
           ON ad.id = dt.dataid 
      WHERE ad.defid = 3070056 
     ) ad
WHERE seqnum = 1;

窗口函数的性能应优于JOINGROUP BY