查询中的多个隐式连接和显式连接

时间:2013-03-04 10:50:08

标签: sql database oracle join

我有一个问题:

SELECT THDR.FILENAME,
       SOURCE.TXN_SOURCE_CD AS TXN_SOURCE_CD,
       SOURCE.DESCR as TXN_SOURCE,
       THDR.TXN_HEADER_ID,
       THDR.TXN_HEADER_EXT_ID,
       THDR.TXN_HEADER_DTTM,
       THDR.UPLOAD_DTTM,
       L.DESCR,
       NVL(SUM(TDTL.TXN_VOL), 0) TOTAL_VOLUME
  FROM ci_lookup_val_l L,
       ci_txn_source_l source,
       CI_TXN_HEADER   THDR
  LEFT JOIN ci_txn_detail TDTL 
  ON THDR.TXN_HEADER_ID = TDTL.TXN_HEADER_ID        

 WHERE TRIM(SOURCE.TXN_SOURCE_CD) = TRIM(TDTL.TXN_SOURCE_CD)
   AND SOURCE.LANGUAGE_CD = 'ENG'      
   AND L.FIELD_NAME = 'TXN_HEADER_STATUS'
   AND THDR.BO_STATUS_CD = L.FIELD_VALUE
   AND L.LANGUAGE_CD = 'ENG'
   AND THDR.TXN_HEADER_ID='22222228'
 GROUP BY THDR.FILENAME,SOURCE.DESCR,THDR.TXN_HEADER_ID,THDR.TXN_HEADER_EXT_ID,THDR.TXN_HEADER_DTTM,THDR.UPLOAD_DTTM,L.DESCR,SOURCE.TXN_SOURCE_CD

如您所见,此查询具有多个隐式连接和一个显式连接。这是我第一次使用这种查询但它编译。但是,此查询中的左连接不起作用。也就是说,如果我在TDTL上没有与THDR上的记录相对应的记录,则查询不会返回任何行。

你能帮我解决一下吗?

5 个答案:

答案 0 :(得分:2)

我的建议是将您的查询更改为为每个人使用显式连接:

SELECT THDR.FILENAME,
       SOURCE.TXN_SOURCE_CD AS TXN_SOURCE_CD,
       SOURCE.DESCR as TXN_SOURCE,
       THDR.TXN_HEADER_ID,
       THDR.TXN_HEADER_EXT_ID,
       THDR.TXN_HEADER_DTTM,
       THDR.UPLOAD_DTTM,
       L.DESCR,
       NVL(SUM(TDTL.TXN_VOL), 0) TOTAL_VOLUME
FROM ci_lookup_val_l L
INNER JOIN CI_TXN_HEADER   THDR
  ON THDR.BO_STATUS_CD = L.FIELD_VALUE
LEFT JOIN ci_txn_detail TDTL 
  ON THDR.TXN_HEADER_ID = TDTL.TXN_HEADER_ID       
LEFT JOIN ci_txn_source_l source
  on TRIM(SOURCE.TXN_SOURCE_CD) = TRIM(TDTL.TXN_SOURCE_CD)
  AND SOURCE.LANGUAGE_CD = 'ENG' 
WHERE L.FIELD_NAME = 'TXN_HEADER_STATUS' 
   AND L.LANGUAGE_CD = 'ENG'
   AND THDR.TXN_HEADER_ID='22222228'
GROUP BY THDR.FILENAME,
  SOURCE.DESCR,
  THDR.TXN_HEADER_ID,
  THDR.TXN_HEADER_EXT_ID,
  THDR.TXN_HEADER_DTTM,
  THDR.UPLOAD_DTTM,
  L.DESCR,
  SOURCE.TXN_SOURCE_CD

答案 1 :(得分:1)

问题是这个条件:

 WHERE TRIM(SOURCE.TXN_SOURCE_CD) = TRIM(TDTL.TXN_SOURCE_CD)

如果TDTL中没有匹配的条目,则TDTL.TXN_SOURCE_CD将为NULL,并且该记录将被拒​​绝。

您需要重新考虑涉及SOURCE的(隐式内部)联接。

答案 2 :(得分:1)

你可以在法令中使用以下条款,

WHERE TRIM(NVL(SOURCE.TXN_SOURCE_CD, 'NULL')) = TRIM(NVL(TDTL.TXN_SOURCE_CD, 'NULL'))

如果您还要检查空值。看看是否有效

答案 3 :(得分:1)

这很难遵循,但转换为使用一致的连接语法有点帮助。提供数据和预期结果会有所帮助,因此这在很大程度上是一种猜测。但问题似乎在于:

WHERE TRIM(SOURCE.TXN_SOURCE_CD) = TRIM(TDTL.TXN_SOURCE_CD)

由于这是在SOURCETDTL之间强制执行内部联接条件,因此THDRTDTL之间的左外联接实际上也成为了内部联接。你真的需要将它移动到外连接中。

这样的东西看起来应该给你想要的东西,但仍然不仅仅是一个猜测:

SELECT THDR.FILENAME,
       SOURCE.TXN_SOURCE_CD AS TXN_SOURCE_CD,
       SOURCE.DESCR as TXN_SOURCE,
       THDR.TXN_HEADER_ID,
       THDR.TXN_HEADER_EXT_ID,
       THDR.TXN_HEADER_DTTM,
       THDR.UPLOAD_DTTM,
       L.DESCR,
       NVL(SUM(TDTL.TXN_VOL), 0) TOTAL_VOLUME
  FROM ci_lookup_val_l L
  JOIN ci_txn_source_l SOURCE
    ON SOURCE.LANGUAGE_CD = L.LANGUAGE_CD
  JOIN CI_TXN_HEADER THDR
    ON THDR.BO_STATUS_CD = L.FIELD_VALUE
  LEFT JOIN ci_txn_detail TDTL 
    ON TDTL.TXN_HEADER_ID = THDR.TXN_HEADER_ID        
   AND TRIM(TDTL.TXN_SOURCE_CD) = TRIM(SOURCE.TXN_SOURCE_CD)
 WHERE L.FIELD_NAME = 'TXN_HEADER_STATUS'
   AND L.LANGUAGE_CD = 'ENG'
   AND THDR.TXN_HEADER_ID = '22222228'
 GROUP BY THDR.FILENAME,SOURCE.DESCR,THDR.TXN_HEADER_ID,THDR.TXN_HEADER_EXT_ID,
           THDR.TXN_HEADER_DTTM,THDR.UPLOAD_DTTM,L.DESCR,SOURCE.TXN_SOURCE_CD;

但如果TRIM(TDTL.TXN_SOURCE_CD)TRIM(SOURCE.TXN_SOURCE_CD)可能为空,那么该比较将无效,但您根本不清楚自己想要发生什么。你可以这样做:

  LEFT JOIN ci_txn_detail TDTL 
    ON TDTL.TXN_HEADER_ID = THDR.TXN_HEADER_ID        
   AND ((TRIM(TDTL.TXN_SOURCE_CD) IS NULL AND TRIM(SOURCE.TXN_SOURCE_CD) IS NULL)
       OR (TRIM(TDTL.TXN_SOURCE_CD) = TRIM(SOURCE.TXN_SOURCE_CD)))

...但是真的不确定会给出你期望的答案(不管是什么!)。

答案 4 :(得分:0)

感谢所有回答这个问题的人。我结合了大多数答案提出的建议来找到实际的解决方案:

SELECT THDR.FILENAME,
       SOURCE.TXN_SOURCE_CD AS TXN_SOURCE_CD,
       SOURCE.DESCR as TXN_SOURCE,
       THDR.TXN_HEADER_ID,
       THDR.TXN_HEADER_EXT_ID,
       THDR.TXN_HEADER_DTTM,
       THDR.UPLOAD_DTTM,
       L.DESCR,
       NVL(SUM(TDTL.TXN_VOL), 0) TOTAL_VOLUME
  FROM ci_lookup_val_l L,
       CI_TXN_HEADER   THDR
  LEFT JOIN ci_txn_detail TDTL 
  ON THDR.TXN_HEADER_ID = TDTL.TXN_HEADER_ID        
  LEFT JOIN ci_txn_source_l source
  ON (TRIM(NVL(SOURCE.TXN_SOURCE_CD, 'NULL')) = TRIM(NVL(TDTL.TXN_SOURCE_CD, 'NULL')) AND SOURCE.LANGUAGE_CD = :LANGUAGE)

 WHERE L.FIELD_NAME = 'TXN_HEADER_STATUS'
   AND THDR.BO_STATUS_CD = L.FIELD_VALUE
   AND L.LANGUAGE_CD = :LANGUAGE

 GROUP BY THDR.FILENAME,SOURCE.DESCR,THDR.TXN_HEADER_ID,THDR.TXN_HEADER_EXT_ID,THDR.TXN_HEADER_DTTM,THDR.UPLOAD_DTTM,L.DESCR,SOURCE.TXN_SOURCE_CD;