我正在进行从Oracle到SQL Datawarehouse Azure的仓库迁移,遇到了这个查询的问题。
来自Oracle的原始查询-它返回1872520
行。
SELECT
*
FROM
STG_REV_APPORTION_CSC_NO t1,
STG_SEP_VL t2,
STG_SEP_VL t3
WHERE
t3.BUSINESS_DATE(+) = t1.BUSINESS_DATE
AND t3.CSC_APP_NO(+) = t1.CSC_APP_NO
AND t3.JOURNEY_NO(+) = t1.JOURNEY_NO
AND t3.PURSE_TXN_CTR(+) = t1.PURSE_TXN_CTR
AND t2.BUSINESS_DATE(+) = t1.BUSINESS_DATE
AND t2.CSC_APP_NO(+) = t1.CSC_APP_NO
AND t2.JOURNEY_NO(+) = t1.JOURNEY_NO
AND
(
t2.TRIP_NO(+) + 1
)
= t1.TRIP_NO
AND
(
t2.MSG_TYPE_CD(+) = 13070
AND t3.MSG_TYPE_CD(+) = 4357
);
从documentation得到线索,我尝试将查询重写为ANSI:
SELECT COUNT(*)
FROM STG_REV_APPORTION_CSC_NO t1
RIGHT OUTER JOIN STG_SEP_VL t3 ON t3.BUSINESS_DATE = t1.BUSINESS_DATE
AND t3.CSC_APP_NO = t1.CSC_APP_NO
AND t3.JOURNEY_NO = t1.JOURNEY_NO
AND t3.PURSE_TXN_CTR = t1.PURSE_TXN_CTR
RIGHT OUTER JOIN STG_SEP_VL t2 ON t2.BUSINESS_DATE = t1.BUSINESS_DATE
AND t2.CSC_APP_NO = t1.CSC_APP_NO
AND t2.JOURNEY_NO = t1.JOURNEY_NO
AND (t2.TRIP_NO + 1) = t1.TRIP_NO
WHERE t2.MSG_TYPE_CD = 13070 AND t3.MSG_TYPE_CD = 4357
它返回零行。ANSI版本应该在Oracle示例上工作-它也返回零行。
然后我尝试使用toad上的重构选项将plus join转换为ANSI。
SELECT *
FROM STG_SEP_VL T2
RIGHT OUTER JOIN STG_REV_APPORTION_CSC_NO T1
ON (T2.BUSINESS_DATE = T1.BUSINESS_DATE)
AND (T2.CSC_APP_NO = T1.CSC_APP_NO)
AND (T2.JOURNEY_NO = T1.JOURNEY_NO)
RIGHT OUTER JOIN STG_SEP_VL T3
ON (T3.PURSE_TXN_CTR = T1.PURSE_TXN_CTR)
AND (T3.BUSINESS_DATE = T1.BUSINESS_DATE)
AND (T3.CSC_APP_NO = T1.CSC_APP_NO)
AND (T3.JOURNEY_NO = T1.JOURNEY_NO)
WHERE ( ( (T2.TRIP_NO /*(+)*/
) + 1) = T1.TRIP_NO)
AND ( ( (T2.MSG_TYPE_CD /*(+)*/
) = 13070) AND ( (T3.MSG_TYPE_CD /*(+)*/
) = 4357));
现在,这个查询应该在Oracle上运行,并且在我可以在SQL Server上运行它之前返回相同的行数。
我查看了这两个查询的explain计划。下面是(+)join计划的样子:
下面是该查询的ANSI版本的外观:
我错过什么了吗?
3条答案
按热度按时间b09cbbtk1#
这是我得出的结论:
表t2和t3是t1的外部联接,因此您可以先列出t1并执行左联接,或者先列出t2和t3并执行右联接。
ibrsph3r2#
没有样本数据很难确定,但我认为哪里条款是罪魁祸首。
在where子句中包含来自t2和t3的字段会取消外部连接的效果,除非您还允许空值(
t2.MSG_TYPE_CD = 13070 OR 2.MSG_TYPE_CD IS NULL
)。将这些过滤器移动到连接中会允许不匹配的记录进入结果。我不是100%确信这个查询是正确的。我怀疑应该用左外连接替换右外连接。这将返回来自t1的所有记录,只有来自t2和t3的匹配记录。
xpcnnkqh3#
很难找到这种不匹配的确切原因,但我认为您已经交换了表STG_SEP_VL中PURSE_TXN_CTR列的连接条件。