基于主查询的嵌套查询选择

时间:2013-11-29 03:17:27

标签: sql performance db2

我想将嵌套查询的选择仅限于主查询选择。但是当我尝试这样做时,它会返回错误。请参阅以下查询:

SELECT DISTINCT A.VBELN, C.MBLNR
FROM LIKP AS A  
INNER JOIN VBUK AS B ON B.MANDT = A.MANDT AND B.VBELN = A.VBELN   
LEFT JOIN (
    SELECT DISTINCT MANDT, XBLNR, MBLNR
    FROM MKPF
    WHERE MANDT='200'
         AND MBLNR NOT IN ( SELECT DISTINCT SMBLN FROM MSEG WHERE MANDT='200' )
         --AND XBLNR=A.VBELN ---> I would like to add this line, but it's error
) AS C ON C.MANDT = A.MANDT AND C.XBLNR = A.VBELN
WHERE A.MANDT='200'  
      AND a.lfdat BETWEEN '20131203' AND '20131205'  
      AND b.wbstk <> 'C'
ORDER BY A.VBELN 
FETCH FIRST 200 ROWS ONLY 
OPTIMIZE FOR 200 ROWS

错误是:

"A.VBELN" is an undefined name.. SQLCODE=-204, SQLSTATE=42704, DRIVER=3.66.46 SQL Code: -204, SQL State: 42704

如果我不使用此行:AND XBLNR=A.VBELN,则需要更长时间才能获得结果。因为虽然我使用了fetch firstoptimize条款,但仍需要很长时间。我怎样才能做到这一点?感谢。

4 个答案:

答案 0 :(得分:1)

尝试LATERAL keyword,如下所示:

...
INNER JOIN VBUK AS B ON B.MANDT = A.MANDT AND B.VBELN = A.VBELN   
LEFT JOIN   LATERAL   (                   -- <<< here
  SELECT DISTINCT MANDT, XBLNR, MBLNR
...

答案 1 :(得分:0)

我从未使用过db2,所以可能有更好的方法来优化它,但你总是可以重复内部的选择:

SELECT DISTINCT A.VBELN, C.MBLNR
FROM LIKP AS A  
INNER JOIN VBUK AS B ON B.MANDT = A.MANDT AND B.VBELN = A.VBELN   
LEFT JOIN (
    SELECT DISTINCT MANDT, XBLNR, MBLNR
    FROM MKPF AS M
    INNER JOIN (
        SELECT DISTINCT A.VBELN, C.MBLNR
        FROM LIKP AS L 
    ) ON M.XBLNR = L.VBELN
    WHERE MANDT='200'
    AND MBLNR NOT IN ( SELECT DISTINCT SMBLN FROM MSEG WHERE MANDT='200' )
) AS C ON C.MANDT = A.MANDT AND C.XBLNR = A.VBELN
WHERE A.MANDT='200'  
AND a.lfdat BETWEEN '20131203' AND '20131205'  
AND b.wbstk <> 'C'
ORDER BY A.VBELN 
FETCH FIRST 200 ROWS ONLY 
OPTIMIZE FOR 200 ROWS

答案 2 :(得分:0)

--CREATE a TABLE TO hold the result OF this part OF the query

TempTable = (SELECT * FROM  LIKP
WHERE A.MANDT='200'  
      AND a.lfdat BETWEEN '20131203' AND '20131205')



SELECT DISTINCT A.VBELN, C.MBLNR
FROM
TempTable A  
INNER JOIN VBUK AS B ON B.MANDT = A.MANDT AND B.VBELN = A.VBELN   
LEFT JOIN (
    SELECT DISTINCT MANDT, XBLNR, MBLNR
    FROM MKPF
    WHERE MANDT='200'
         AND MBLNR NOT IN ( SELECT DISTINCT SMBLN FROM MSEG WHERE MANDT='200' )
         AND XBLNR=TempTable.VBELN 
) AS C ON C.MANDT = A.MANDT AND C.XBLNR = A.VBELN
      AND b.wbstk <> 'C'
ORDER BY A.VBELN 
FETCH FIRST 200 ROWS ONLY 
OPTIMIZE FOR 200 ROWS

然后去尝试删除C的不同,否定和不存在。如果删除其中一个或多个,查询将执行得更快。尝试查看执行计划并更新您的问题。

答案 3 :(得分:0)

如何删除区别并使用连接来减少数据集?

SELECT 
    DISTINCT 
        A.VBELN, 
        C.MBLNR
FROM 
    LIKP AS A  

    INNER JOIN VBUK AS B 
        ON B.MANDT = A.MANDT AND B.VBELN = A.VBELN   

    LEFT JOIN 
    (
            SELECT 
                X.MANDT, 
                X.XBLNR, 
                X.MBLNR0
            FROM 
                MKPF X
                INNER JOIN MSEG Y 
                    ON  X.MBLNR != Y.SMBLN 
                        AND X.MANDT='200' 
                        AND Y.MANDT = '200'
    )    C 
        ON  C.MANDT = A.MANDT AND C.XBLNR = A.VBELN
WHERE 
    A.LFDAT BETWEEN '20131203' AND '20131205'  
    AND B.WBSTK <> 'C'
ORDER BY 
    A.VBELN 

FETCH FIRST 200 ROWS ONLY 
OPTIMIZE FOR 200 ROWS