LEFT JOIN ON COALESCE(a,b,c) - 非常奇怪的行为

时间:2014-09-23 16:40:58

标签: sql oracle left-join coalesce

我的查询遇到了非常奇怪的行为,我浪费了很多时间来理解导致它的原因。所以我在寻求你的帮助。

  

SELECT count(*)FROM main_table
  LEFT JOIN front_table ON front_table.pk = main_table.fk_front_table
  LEFT JOIN info_table ON info_table.pk = front_table.fk_info_table
  LEFT JOIN key_table ON key_table.pk = COALESCE(info_table.fk_key_table,front_table.fk_key_table_1,front_table.fk_key_table_2)
  LEFT JOIN side_table ON side_table.fk_front_table = front_table.pk

     

WHERE side_table.pk =(SELECT MAX(pk)FROM side_table WHERE fk_front_table = front_table.pk)
  或side_table.pk IS NULL

看起来像一个简单的连接查询,有了合并,我之前使用过这种技术(不是很多次),它运作正常。

在此查询中,我不会为side_table.pk获取空值。如果我删除coalesce或者只是不使用key_table,那么查询将返回带有许多null side_table.pk的行,但是如果我添加coalesce join,我就无法获得这些空值。

似乎key_table和side_table没有任何共同之处,但结果却很奇怪。

另外,当我不使用side_table和WHERE子句时,count(*)结果与coalesce没有差别,但我看不到行中的任何模式丢失,它似乎是随机的!

真实查询:

  SELECT ECHANGE.EXC_AUTO_KEY, STOCK_RESERVATIONS.STR_AUTO_KEY FROM EXCHANGE
            LEFT JOIN WO_BOM ON WO_BOM.WOB_AUTO_KEY = EXCHANGE.WOB_AUTO_KEY
            LEFT JOIN VIEW_WO_SUB ON VIEW_WO_SUB.WOO_AUTO_KEY = WO_BOM.WOO_AUTO_KEY
            LEFT JOIN STOCK stock3 ON stock3.STM_AUTO_KEY = EXCHANGE.STM_AUTO_KEY
            LEFT JOIN STOCK stock2 ON stock2.STM_AUTO_KEY = EXCHANGE.ORIG_STM
            LEFT JOIN CONSIGNMENT_CODES con2 ON con2.CNC_AUTO_KEY = stock2.CNC_AUTO_KEY
            LEFT JOIN CONSIGNMENT_CODES con3 ON con3.CNC_AUTO_KEY = stock3.CNC_AUTO_KEY
            LEFT JOIN CI_UTL ON CI_UTL.CUT_AUTO_KEY = EXCHANGE.CUT_AUTO_KEY
            LEFT JOIN PART_CONDITION_CODES pcc2 ON pcc2.PCC_AUTO_KEY = stock2.PCC_AUTO_KEY
            LEFT JOIN PART_CONDITION_CODES pcc3 ON pcc3.PCC_AUTO_KEY = stock3.PCC_AUTO_KEY
            LEFT JOIN STOCK_RESERVATIONS ON STOCK_RESERVATIONS.STM_AUTO_KEY = stock3.STM_AUTO_KEY
            LEFT JOIN WAREHOUSE wh2 ON wh2.WHS_AUTO_KEY = stock2.WHS_ORIGINAL
            LEFT JOIN SM_HISTORY ON (SM_HISTORY.STM_AUTO_KEY = EXCHANGE.ORIG_STM AND SM_HISTORY.WOB_REF = EXCHANGE.WOB_AUTO_KEY)
            LEFT JOIN RC_DETAIL ON stock3.RCD_AUTO_KEY = RC_DETAIL.RCD_AUTO_KEY
            LEFT JOIN RC_HEADER ON RC_HEADER.RCH_AUTO_KEY = RC_DETAIL.RCH_AUTO_KEY
            LEFT JOIN WAREHOUSE wh3 ON wh3.WHS_AUTO_KEY = COALESCE(RC_DETAIL.WHS_AUTO_KEY, stock3.WHS_ORIGINAL, stock3.WHS_AUTO_KEY)
            WHERE STOCK_RESERVATIONS.STR_AUTO_KEY = (SELECT MAX(STR_AUTO_KEY) FROM STOCK_RESERVATIONS WHERE STM_AUTO_KEY = stock3.STM_AUTO_KEY) OR STOCK_RESERVATIONS.STR_AUTO_KEY IS NULL

删除LEFT JOIN WAREHOUSE wh3为我提供了带有大量NULL STR_AUTO_KEY的唯一EXC_AUTO_KEY值,而保留此行会删除所有NULL STR_AUTO_KEY。

我重新创建了具有相同结构和查询的数字的简单表,没有任何问题o.0

2 个答案:

答案 0 :(得分:0)

我有一种感觉COALESCE充当了联接表的REQUIRED标志,因此将LEFT JOIN作为INNER JOIN拍摄。

试试这个:

SELECT COUNT(*) 
FROM main_table
  LEFT JOIN front_table ON front_table.pk = main_table.fk_front_table
  LEFT JOIN info_table ON info_table.pk = front_table.fk_info_table
  LEFT JOIN key_table ON key_table.pk = NVL(info_table.fk_key_table, NVL(front_table.fk_key_table_1, front_table.fk_key_table_2))
  LEFT JOIN (SELECT fk_, MAX(pk) as pk FROM side_table GROUP BY fk_) st ON st.fk_ = front_table.pk

NVL可能表现得差不多......

答案 1 :(得分:0)

我知道问题是什么(不完全是这样):原始查询中存在LEFT JOIN VIEW_WO_SUB,第3行。它导致此查询以奇怪的方式运行。

当我用包含我需要的信息的另一个表替换视图时,查询开始返回正确的结果。

基本上,使用此视图连接,NVL,COALESCE或CASE连接与某些参数的组合在WHERE子查询中不与OR子句一起使用,所有其余的都很好。虽然,我可以通过更改连接表的顺序来获取查询以使用此视图连接,但我必须将表参与子查询放在底部。