2

有谁知道为什么下面的 SQL 语句需要永远加载???

select LE_ACNT_STKG.ID_PRD_RP
from       
    TR_LTM_PHY_CNT  
    inner join AS_ITM_STK   ON (AS_ITM_STK.ID_STR_RT = TR_LTM_PHY_CNT.ID_STR_RT
                            and AS_ITM_STK.ID_ITM = TR_LTM_PHY_CNT.ID_ITM)  
    inner join LE_ACNT_STKG ON (LE_ACNT_STKG.ID_STR_RT = TR_LTM_PHY_CNT.ID_STR_RT  
                            and LE_ACNT_STKG.ID_ITM = TR_LTM_PHY_CNT.ID_ITM)  
    inner JOIN AS_ITM       ON (AS_ITM.ID_ITM = AS_ITM_STK.ID_ITM and AS_ITM.ID_STR_RT = AS_ITM_STK.ID_STR_RT)  
    inner join LO_LCN       ON (LE_ACNT_STKG.ID_LCN = LO_LCN.ID_LCN) 
    INNER JOIN DO_CNT_PHY   on  TR_LTM_PHY_CNT.ID_DCM_PHY_CNT = DO_CNT_PHY.ID_DCM_PHY_CNT  
    INNER JOIN CO_EV        on (DO_CNT_PHY.ID_STR_RT         = CO_EV.ID_STR_RT  
                            and DO_CNT_PHY.ID_EV         = CO_EV.ID_EV)                                     
where   
    LE_ACNT_STKG.ID_PRD_RP >= 4792
    AND LE_ACNT_STKG.ID_PRD_RP <= 6693
    AND LE_ACNT_STKG.ID_PRD_RP IN (
                    SELECT TOP 1 LE_ACNT_STKG.ID_PRD_RP 
                    FROM LE_ACNT_STKG 
                    INNER JOIN CA_PRD_RP ON (LE_ACNT_STKG.ID_PRD_RP = CA_PRD_RP.ID_PRD_RP)
                    WHERE 
                        CA_PRD_RP.TY_PRD_RP = 'CD' AND
                        LE_ACNT_STKG.ID_STR_RT = TR_LTM_PHY_CNT.ID_STR_RT AND
                        LE_ACNT_STKG.ID_ITM = TR_LTM_PHY_CNT.ID_ITM AND
                        (
                          (CA_PRD_RP.TS_PRD_RP_STRT <= CO_EV.TS_EV_ACT_EF AND CA_PRD_RP.TS_PRD_RP_END  >= CO_EV.TS_EV_ACT_EF) 
                           OR --If we're in the latest period, which is still open
                          (CA_PRD_RP.TS_PRD_RP_STRT <= CO_EV.TS_EV_ACT_EF AND CA_PRD_RP.TS_PRD_RP_END  IS NULL) 
                           OR --if there isn't one for the current period, get the previous one
                          (CA_PRD_RP.TS_PRD_RP_END < CO_EV.TS_EV_ACT_EF)
                        )
                    ORDER BY
                        LE_ACNT_STKG.ID_PRD_RP DESC)

我相信这是因为IN()子查询。当我取出该语句时,它的加载速度要快得多。如果是这种情况,我该怎么办?我尝试用 替换INEXISTS但返回的结果完全不同。

4

5 回答 5

0

我认为您可以像这样简单地使用 group by 查询:

select distinct SUB.ID_PRD_RP from (
  select CA_PRD_RP.ID_PRD_RP,MAX(LE_ACNT_STKG.ID_PRD_RP) AS ID_PRD_RP
  from       
      TR_LTM_PHY_CNT  
      inner join AS_ITM_STK   ON (AS_ITM_STK.ID_STR_RT = TR_LTM_PHY_CNT.ID_STR_RT
                  and AS_ITM_STK.ID_ITM = TR_LTM_PHY_CNT.ID_ITM)  
      inner join LE_ACNT_STKG ON (LE_ACNT_STKG.ID_STR_RT = TR_LTM_PHY_CNT.ID_STR_RT  
                  and LE_ACNT_STKG.ID_ITM = TR_LTM_PHY_CNT.ID_ITM)  
      inner JOIN AS_ITM       ON (AS_ITM.ID_ITM = AS_ITM_STK.ID_ITM and AS_ITM.ID_STR_RT = AS_ITM_STK.ID_STR_RT)  
      inner join LO_LCN       ON (LE_ACNT_STKG.ID_LCN = LO_LCN.ID_LCN) 
      INNER JOIN DO_CNT_PHY   on  TR_LTM_PHY_CNT.ID_DCM_PHY_CNT = DO_CNT_PHY.ID_DCM_PHY_CNT  
      INNER JOIN CO_EV        on (DO_CNT_PHY.ID_STR_RT = CO_EV.ID_STR_RT  
                  and DO_CNT_PHY.ID_EV = CO_EV.ID_EV)                                     
      INNER JOIN CA_PRD_RP ON (LE_ACNT_STKG.ID_PRD_RP = CA_PRD_RP.ID_PRD_RP)
  where   
      LE_ACNT_STKG.ID_PRD_RP >= 4792
      AND LE_ACNT_STKG.ID_PRD_RP <= 6693
      AND CA_PRD_RP.TY_PRD_RP = 'CD'
      AND (
      (CA_PRD_RP.TS_PRD_RP_STRT <= CO_EV.TS_EV_ACT_EF AND CA_PRD_RP.TS_PRD_RP_END  >= CO_EV.TS_EV_ACT_EF) 
        OR --If we're in the latest period, which is still open
      (CA_PRD_RP.TS_PRD_RP_STRT <= CO_EV.TS_EV_ACT_EF AND CA_PRD_RP.TS_PRD_RP_END  IS NULL) 
          OR --if there isn't one for the current period, get the previous one
      (CA_PRD_RP.TS_PRD_RP_END < CO_EV.TS_EV_ACT_EF)
    )
  GROUP BY
    CA_PRD_RP.ID_PRD_RP) SUB
于 2013-01-03T10:19:41.247 回答
0

将子查询的结果转储到临时表中,然后将该临时表连接到主查询。

SELECT
    LE_ACNT_STKG.ID_PRD_RP
INTO
    #MyFirstTempTable
FROM
    LE_ACNT_STKG 
INNER JOIN
    CA_PRD_RP
    ON (LE_ACNT_STKG.ID_PRD_RP = CA_PRD_RP.ID_PRD_RP)
WHERE 
    CA_PRD_RP.TY_PRD_RP = 'CD' AND
    LE_ACNT_STKG.ID_STR_RT = TR_LTM_PHY_CNT.ID_STR_RT AND
    LE_ACNT_STKG.ID_ITM = TR_LTM_PHY_CNT.ID_ITM AND
    (
        (CA_PRD_RP.TS_PRD_RP_STRT <= CO_EV.TS_EV_ACT_EF AND CA_PRD_RP.TS_PRD_RP_END  >= CO_EV.TS_EV_ACT_EF) 
        OR --If we're in the latest period, which is still open
        (CA_PRD_RP.TS_PRD_RP_STRT <= CO_EV.TS_EV_ACT_EF AND CA_PRD_RP.TS_PRD_RP_END  IS NULL) 
        OR --if there isn't one for the current period, get the previous one
        (CA_PRD_RP.TS_PRD_RP_END < CO_EV.TS_EV_ACT_EF)
     )
于 2013-01-03T09:35:20.993 回答
0

cipet huat 这样做,

select LE_ACNT_STKG.ID_PRD_RP
from       
    TR_LTM_PHY_CNT  
    inner join AS_ITM_STK   ON (AS_ITM_STK.ID_STR_RT = TR_LTM_PHY_CNT.ID_STR_RT
                            and AS_ITM_STK.ID_ITM = TR_LTM_PHY_CNT.ID_ITM)  
    inner join LE_ACNT_STKG ON (LE_ACNT_STKG.ID_STR_RT = TR_LTM_PHY_CNT.ID_STR_RT  
                            and LE_ACNT_STKG.ID_ITM = TR_LTM_PHY_CNT.ID_ITM)  
    inner JOIN AS_ITM       ON (AS_ITM.ID_ITM = AS_ITM_STK.ID_ITM and AS_ITM.ID_STR_RT = AS_ITM_STK.ID_STR_RT)  
    inner join LO_LCN       ON (LE_ACNT_STKG.ID_LCN = LO_LCN.ID_LCN) 
    INNER JOIN DO_CNT_PHY   on  TR_LTM_PHY_CNT.ID_DCM_PHY_CNT = DO_CNT_PHY.ID_DCM_PHY_CNT  
    INNER JOIN CO_EV        on (DO_CNT_PHY.ID_STR_RT         = CO_EV.ID_STR_RT  
                            and DO_CNT_PHY.ID_EV         = CO_EV.ID_EV)                                     
    inner join 
                    SELECT TOP 1 LE_ACNT_STKG.ID_PRD_RP 
                    FROM LE_ACNT_STKG 
                    INNER JOIN CA_PRD_RP ON (LE_ACNT_STKG.ID_PRD_RP = CA_PRD_RP.ID_PRD_RP)
                    WHERE 
                        CA_PRD_RP.TY_PRD_RP = 'CD' AND
                        LE_ACNT_STKG.ID_STR_RT = TR_LTM_PHY_CNT.ID_STR_RT AND
                        LE_ACNT_STKG.ID_ITM = TR_LTM_PHY_CNT.ID_ITM AND
                        (
                          (CA_PRD_RP.TS_PRD_RP_STRT <= CO_EV.TS_EV_ACT_EF AND CA_PRD_RP.TS_PRD_RP_END  >= CO_EV.TS_EV_ACT_EF) 
                           OR --If we're in the latest period, which is still open
                          (CA_PRD_RP.TS_PRD_RP_STRT <= CO_EV.TS_EV_ACT_EF AND CA_PRD_RP.TS_PRD_RP_END  IS NULL) 
                           OR --if there isn't one for the current period, get the previous one
                          (CA_PRD_RP.TS_PRD_RP_END < CO_EV.TS_EV_ACT_EF)
                        )
                    ORDER BY
                        LE_ACNT_STKG.ID_PRD_RP DESC) temp
   on temp.ID_PRD_RP = LE_ACNT_STKG.ID_PRD_RP
where   
    LE_ACNT_STKG.ID_PRD_RP >= 4792
    AND LE_ACNT_STKG.ID_PRD_RP <= 6693
于 2013-01-03T10:27:55.917 回答
0

可惜没有 DDL 很难测试,表名很糟糕 ^^ 这可能是朝着正确方向迈出的一步,但很难确定!

;WITH CTE0 AS
(
    SELECT   ID_PRD_RP  = TR.ID_STR_RT
            ,TR.ID_ITM
            ,ID_PRD_RP  = MAX(LE.ID_PRD_RP) 
    FROM LE_ACNT_STKG   LE 
    JOIN CA_PRD_RP      CA  ON LE.ID_PRD_RP = CA.ID_PRD_RP
    JOIN TR_LTM_PHY_CNT TR  ON TR.ID_STR_RT = LE.ID_STR_RT AND LE.ID_ITM = TR.ID_ITM
    JOIN DO_CNT_PHY     DO  ON  TR_LTM_PHY_CNT.ID_DCM_PHY_CNT = DO.ID_DCM_PHY_CNT
    JOIN CO_EV          CO  ON (DO.ID_STR_RT = CO.ID_STR_RT and DO.ID_EV = CO.ID_EV)
    WHERE CA_PRD_RP.TY_PRD_RP = 'CD' 
    AND (
            (CA.TS_PRD_RP_STRT <= CO.TS_EV_ACT_EF AND CA.TS_PRD_RP_END  >= CO.TS_EV_ACT_EF) 
            OR --If we're in the latest period, which is still open
            (CA.TS_PRD_RP_STRT <= CO.TS_EV_ACT_EF AND CA.TS_PRD_RP_END  IS NULL) 
            OR --if there isn't one for the current period, get the previous one
            (CA.TS_PRD_RP_END < CO.TS_EV_ACT_EF)
        )
    GROUP BY TR.ID_STR_RT, TR.ID_ITM
)
SELECT LE_ACNT_STKG.ID_PRD_RP
FROM TR_LTM_PHY_CNT  
JOIN AS_ITM_STK     ON (AS_ITM_STK.ID_STR_RT = TR_LTM_PHY_CNT.ID_STR_RT
                            and AS_ITM_STK.ID_ITM = TR_LTM_PHY_CNT.ID_ITM)  
join LE_ACNT_STKG   ON (LE_ACNT_STKG.ID_STR_RT = TR_LTM_PHY_CNT.ID_STR_RT and LE_ACNT_STKG.ID_ITM = TR_LTM_PHY_CNT.ID_ITM)  
JOIN AS_ITM         ON (AS_ITM.ID_ITM = AS_ITM_STK.ID_ITM and AS_ITM.ID_STR_RT = AS_ITM_STK.ID_STR_RT)  
join LO_LCN         ON (LE_ACNT_STKG.ID_LCN = LO_LCN.ID_LCN) 
JOIN DO_CNT_PHY     ON  TR_LTM_PHY_CNT.ID_DCM_PHY_CNT = DO_CNT_PHY.ID_DCM_PHY_CNT  
JOIN CO_EV          ON (DO_CNT_PHY.ID_STR_RT         = CO_EV.ID_STR_RT and DO_CNT_PHY.ID_EV = CO_EV.ID_EV)   
JOIN CTE0   CTE ON CTE.ID_PRD_RP =    LE_ACNT_STKG.ID_PRD_RP                               
WHERE LE_ACNT_STKG.ID_PRD_RP >= 4792
AND LE_ACNT_STKG.ID_PRD_RP <= 6693
于 2013-01-03T10:42:58.073 回答
-1

inner join ( SELECT TOP 1 LE_ACNT_STKG.ID_PRD_RP FROM LE_ACNT_STKG INNER JOIN CA_PRD_RP ON (LE_ACNT_STKG.ID_PRD_RP = CA_PRD_RP.ID_PRD_RP) WHERE CA_PRD_RP.TY_PRD_RP = 'CD' AND LE_ACNT_STKG.ID_STR_RT = TR_LTM_PHY_CNT.ID_STR_RT AND LE_ACNT_STKG.ID_ITM = TR_LTM_PHY_CNT.ID_ITM AND ( (CA_PRD_RP.TS_PRD_RP_STRT <= CO_EV.TS_EV_ACT_EF AND CA_PRD_RP.TS_PRD_RP_END >= CO_EV.TS_EV_ACT_EF) 或 -- 如果我们处于最新的时期,该时期仍然开放 (CA_PRD_RP.TS_PRD_RP_STRT <= CO_EV.TS_EV_ACT_EF AND CA_PRD_RP.TS_PRD_RP_END 为空) 或 -- 如果没有't 一个当前周期,获取前一个 (CA_PRD_RP.TS_PRD_RP_END < CO_EV.TS_EV_ACT_EF) ) ORDER BY LE_ACNT_STKG.ID_PRD_RP DESC) ) temp.ID_PRD_RP = LE_ACNT_STKG.ID_PRD_RP

于 2013-01-03T10:38:14.017 回答