我的查询遇到了非常奇怪的行为,我浪费了很多时间来理解导致它的原因。所以我在寻求你的帮助。
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.pkWHERE 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
答案 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子句一起使用,所有其余的都很好。虽然,我可以通过更改连接表的顺序来获取查询以使用此视图连接,但我必须将表参与子查询放在底部。