SQL IN或EXISTS子句问题

时间:2013-05-07 19:57:51

标签: sql plsql subquery

我有两个单独的查询,我想要结合,但我很难得到我想要的结果。一个汇总表中的所有值,另一个根据最近的日期选择重复的行。

第一个查询的缩短版本是:

SELECT a.PLANT_NO "PlantNumber", 
       SUM(CASE WHEN a.REC_STATUS_CD = 'RR' THEN -a.KW_CTR_REDELIVERED_HV 
                ELSE a.KW_CTR_REDELIVERED_HV END) "KeepWholeResidueMMBtu", 
       SUM(a.ETH_APPLIED_POP_PCT + a.ISO_APPLIED_POP_PCT  + 
           (CASE WHEN a.PLANT_NO = '002' THEN a.ALTLIQ_APPLIED_POP_PCT ELSE 0 END)
          )/100 "NGLPOPPaymentPercent"
FROM GAS_STMT a 
INNER JOIN SETTLE_SUMMARY c
   ON CASE WHEN SUBSTR(a.TRNX_ID,1,1) = '-' 
           THEN SUBSTR(a.TRNX_ID, 2, LENGTH(a.TRNX_ID)) 
           ELSE CAST(a.TRNX_ID AS VARCHAR2(100)) 
      END = c.TRNX_ID
  AND a.MTR_NO||a.MTR_SFX = c.MTR_NO||c.MTR_SFX
WHERE TO_CHAR(a.PROD_DT, 'YYYY')  >= TO_CHAR(ADD_MONTHS(SYSDATE, -36), 'YYYY') 
  AND a.STATUS_UNIT_TM_CD = 'M' 
GROUP BY a.PLANT_NO
ORDER BY a.PLANT_NO

另一个查询用于根据最近的交易日期筛选出四个交易。

SELECT a.*
FROM GAS_STMT a,
     (SELECT MTR_NO,MTR_SFX,TRNX_ID,REC_STATUS_CD,MAX(ACCT_DT) ACCT_DT
      FROM GAS_STMT
      WHERE REC_STATUS_CD = 'RR'
      GROUP BY MTR_NO, MTR_SFX, TRNX_ID, REC_STATUS_CD
      HAVING COUNT(TRNX_ID) > 1) b
WHERE a.MTR_NO = b.MTR_NO
  AND a.TRNX_ID = b.TRNX_ID AND a.REC_STATUS_CD = b.REC_STATUS_CD
  AND a.ACCT_DT = b.ACCT_DT

我认为我可以使用NOT INNOT EXISTS来使第一个查询与除第二个查询中排除的四个记录之外的所有内容相加。 使用EXISTS我得到与第一个查询相同的结果并使用NOT EXISTS我没有得到任何结果。当我使用IN时,我得到了与我想要的相反的排除记录的总和。

在PL / SQL中有一个很好的方法吗?我很困惑,我没有获得NOT EXISTS查询的任何记录。

第一个查询结果示例:

  
      
  1. Plant_No - 汇总
  2.   
  3. 002 - 100
  4.   
  5. 450 - 50
  6.   
  7. 500 - 50
  8.   

第二个查询结果的示例:

  
      
  1. Trnx_ID - Plant_no - KW_CTR_REDELIVERED_HV
  2.   
  3. 1234 - 002 - -99
  4.   
  5. 1235 - 002 - -99
  6.   

预期结果:

  
      
  1. Plant_No - 汇总
  2.   
  3. 002 - 98.02
  4.   
  5. 450 - 50
  6.   
  7. 500 - 50
  8.   

2 个答案:

答案 0 :(得分:1)

如果您要排除第二个查询返回的记录,请尝试:

SELECT a.PLANT_NO "PlantNumber", 
       SUM(CASE WHEN a.REC_STATUS_CD = 'RR' THEN -a.KW_CTR_REDELIVERED_HV 
                ELSE a.KW_CTR_REDELIVERED_HV END) "KeepWholeResidueMMBtu", 
       SUM(a.ETH_APPLIED_POP_PCT + a.ISO_APPLIED_POP_PCT  + 
           (CASE WHEN a.PLANT_NO = '002' THEN a.ALTLIQ_APPLIED_POP_PCT ELSE 0 END)
          )/100 "NGLPOPPaymentPercent"
FROM GAS_STMT a 
INNER JOIN SETTLE_SUMMARY c
   ON CASE WHEN SUBSTR(a.TRNX_ID,1,1) = '-' 
           THEN SUBSTR(a.TRNX_ID, 2, LENGTH(a.TRNX_ID)) 
           ELSE CAST(a.TRNX_ID AS VARCHAR2(100)) 
      END = c.TRNX_ID
  AND a.MTR_NO||a.MTR_SFX = c.MTR_NO||c.MTR_SFX
LEFT JOIN (SELECT MTR_NO,MTR_SFX,TRNX_ID,REC_STATUS_CD,MAX(ACCT_DT) ACCT_DT
           FROM GAS_STMT
           WHERE REC_STATUS_CD = 'RR'
           GROUP BY MTR_NO, MTR_SFX, TRNX_ID, REC_STATUS_CD
           HAVING COUNT(TRNX_ID) > 1) b
   ON a.MTR_NO = b.MTR_NO 
  AND a.TRNX_ID = b.TRNX_ID 
  AND a.REC_STATUS_CD = b.REC_STATUS_CD 
  AND a.ACCT_DT = b.ACCT_DT
WHERE TO_CHAR(a.PROD_DT, 'YYYY')  >= TO_CHAR(ADD_MONTHS(SYSDATE, -36), 'YYYY') 
  AND a.STATUS_UNIT_TM_CD = 'M' 
  AND b.MTR_NO IS NULL
GROUP BY a.PLANT_NO
ORDER BY a.PLANT_NO

答案 1 :(得分:0)

将第二个查询中的b加入第一个查询,方法与第二个查询相同,即

inner join (SELECT MTR_NO,MTR_SFX,TRNX_ID,REC_STATUS_CD,MAX(ACCT_DT) ACCT_DT
  FROM GAS_STMT
  WHERE REC_STATUS_CD = 'RR'
  GROUP BY MTR_NO, MTR_SFX, TRNX_ID, REC_STATUS_CD
  HAVING COUNT(TRNX_ID) > 1) b 
 on a.MTR_NO = b.MTR_NO
   AND a.TRNX_ID = b.TRNX_ID AND a.REC_STATUS_CD = b.REC_STATUS_CD
   AND a.ACCT_DT = b.ACCT_DT

通过这种方式,您可以从第一个查询获得所有内容,但只能从第二个查询中显示的行中获取