OracleからSQL Datawarehouse Azureへのウェアハウス移行の途中で、この問合せの問題が発生しました。Oracle Plus(+)がANSI変換に結合
Oracleの元のクエリ - それは1872520
の行を返します。 documentationから手がかりを取る
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
);
、私は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のリファクタリングオプションを使用して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上で実行する前に同じ数の行を返す必要があります。しかし、そうではありません - ゼロ行を返します。
これらの両方のクエリの説明計画を見ました。ここでどのように見えるか(+)計画に参加している:
は、このクエリのANSIバージョンはどのように見えるかですか?
すべての '(+)'条件は、 'ON'節で書かなければなりません!この問合せにはWHERE句は必要ありません。 'RIGHT JOIN STG_SEP_VL t2 ON ... AND t2.MSG_TYPE_CD = 13070'。 ORは 'where':' 'WHERE(t2.MSG_TYPE_CD = 13070 OR t2.MSG_TYPE_CD IS NULL/*(t2に存在しない行について)* /' – Mike
で、これは恐ろしいです。場所が間違っているのは残念ですが、あなたがいれば申し訳ありません。どこにエラーがあるのかわかりませんが、AND(t2.TRIP_NO + 1)= t1なので、あなたのクエリはToadリファクタリングされたものよりも正確です。 TRIP_NO'はWHERE節ではなくON節になければなりません。これはa(+)を持つすべてのものに対して有効です。私はあなたの場所で何をしたらいいですか:元のクエリを書き直して、1つのテーブルだけを使用し、次に2つ、次に3を書き直します。そして、1と2と3つのテーブルを使用して結果を比較する適切な構文にクエリを変換します。 –
それは私ではありませんでした、ありがたいことに:) –