Oracle Plus(+)加入ANSI转换 [英] Oracle Plus (+) Joins to ANSI conversion
问题描述
我正在从Oracle迁移到SQL Datawarehouse Azure的仓库中,此查询遇到了问题.
I'm in the middle of a warehouse migration from Oracle to SQL Datawarehouse Azure and ran into an issue with this query.
Oracle的原始查询-它返回1872520
行.
The original query from Oracle - it returns 1872520
rows.
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
);
从
Taking clues from documentation, I tried query re-write to 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实例-那里也返回零行.
It returns zero rows. The ANSI version should work on oracle instance - it returns zero rows there too.
然后我尝试使用蟾蜍上的重构选项将plus join转换为ANSI.我得到以下
I then tried to convert plus join to ANSI using refactor option on toad. I get the following
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上运行它.但事实并非如此-它返回零行.
Now this query should run on Oracle and return the same number of rows before I can run it on SQL Server. But it doesn't - it returns zero rows.
我查看了这两个查询的解释计划.这是(+)加盟计划的样子:
I looked at the explain plan for both of these queries. Here is how (+) join plan looks like:
这是此查询的ANSI版本的样子:
Here is how ANSI version of this query looks like:
我错过了什么吗?
推荐答案
这是我想出的:
SELECT *
FROM stg_rev_apportion_csc_no t1
LEFT JOIN stg_sep_vl t3
ON t1.business_date = t3.business_date AND
t1.csc_app_no = t3.csc_app_no AND
t1.journey_no = t3.journey_no AND
t1.purse_txn_ctr = t3.purse_txn_no AND
4357 = t3.msg_type_cd
LEFT JOIN stg_sep_vl t2
ON t1.business_date = t2.business_date AND
t1.csc_app_no = t2.csc_app_no AND
t1.journey_no = t2.journey_no AND
t1.trip_no = t2.trip_no + 1 AND
13070 = t2.msg_type_cd;
表t2和t3在外部连接到t1,因此您可以先列出t1并进行左连接,或者先列出t2和t3并进行右连接.
Tables t2 and t3 are outer joined to t1, so you either list t1 first and do a left join, or list t2 and t3 first and do a right join.
这篇关于Oracle Plus(+)加入ANSI转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!