2016-07-26 20 views
-1

Rのクエリの1つをOracle SQLクエリに変換しようとする完全なSQL初心者 - 謝辞が誤っている場合は謝罪しますが、明示的にしようとします。Oracle日付の異なる2つの異なるスキーマへの結合

WindowsでのOracle SQL Developer 4.0.3.16の使用。

私は、日付範囲と許可IDに基づいて2つの異なるスキーマ(schAとschB)からテーブル(「VMS」と「TRIP」)を結合しようとしています。私は左結合をしたい(schA.VMSからすべての行を保持し、schBからTRIP_JOINフィールドだけを残す...日付が一致しないときにTRIP_JOINフィールドにNAを残す)。 2 schemas.tableの

説明:

describe schA.VMS 
Name    Null  Type   
----------------- -------- ----------- 
PERMIT      NUMBER(6) 
POSITION_DATETIME NOT NULL DATE   
LATITUDE  NOT NULL NUMBER(9,6) 
LONGITUDE  NOT NULL NUMBER(9,6) 


describe schB.TRIP 
Name      Null  Type   
-------------------------- -------- ------------ 
PERMIT      NOT NULL VARCHAR2(6) 
TRIP_JOIN     NOT NULL NUMBER  
TRIP_START       DATE   
TRIP_END       DATE  

私は、私は、このエラーメッセージが出続ける以下のコード

alter session set nls_date_format = 'mm/dd/yyyy HH24:MI' 

SELECT schA.VMS.*,TRIP_JOIN FROM schA.VMS 
    LEFT JOIN schA.VMS 
    ON schA.VMS.POSITION_DATETIME BETWEEN 
    to_date(schB.TRIP.TRIP_START) AND to_date(schB.TRIP.TRIP_END) 
    WHERE to_char(schA.VMS.PERMIT) = schB.TRIP.PERMIT 

の異なるバージョンをしようとしています。私はスキーマ間で誤って指定していると仮定しますが、私はどのような側面を把握することはできません!

ORA-00904: "schB"."TRIP"."TRIP_END": invalid identifier 
00904. 00000 - "%s: invalid identifier" 
*Cause:  
*Action: 
Error at Line: 20 Column: 115 

私は再現可能な例を提供する方法を理解しようとしましたが、私のオラクルのスキルはあまりまだありません。謝罪し、うまくいけば私の間違いは十分に明らかである!

私の質問のさまざまな部分のためのSOの投稿が見つかりましたが、私はギャップをかなりブリッジした別のものを見つけることができませんでした。

ありがとうございます!ルークの答えとsstanさんのコメントからアドバイスを組み合わせる

+2

あなたのクエリは、自己を実行している(schA.VMS'と 'LEFT schA.VMS'のJOIN FROM') 'schA.VMS'に参加します。あなたは 'schB.TRIP'に全く参加していないので、そのテーブルを参照することはできません。 'from'と' join'節を確認してください。また、テーブルのエイリアスを使用すると、クエリを大幅に簡素化できます。 – sstan

+0

私のような初心者が将来の質問を改善できるように、ダウンボートは説明を伴ってはるかに建設的です。ありがとう! – Jordan

答えて

1

「SCHB」。「TRIP」を選択しようとすると、エラーを取得している。「TRIP_ENDを」あなたは「SCHB」にも参加していませんので。「旅」

+0

これを修正したら、正しい表からNULL値を取得できないという明白な理由はありますか?私はただ彼らが一致する行を取得するように見えますが、私の僅かな理解では、左の結合の代わりに内部の結合です。それは正しいようですか? – Jordan

+0

これは正しくなく、WHERE句によって引き起こされます。代わりに、JOINのON句に含める必要があります。私はこれを反映するために私の答えを更新します。 – mathguy

2

- あなたはおそらくこのようなものがほしいと思うでしょう。

あなたの質問には別の間違いがあります。最初の質問を修正すると明らかになります。 t.TRIP_STARTt.TRIP_ENDは日付ですが、to_date().以内にラップすると、問題が発生する可能性があります。

SELECT v.*, t.TRIP_JOIN 
FROM schA.VMS v LEFT JOIN schB.TRIP t 
    ON v.POSITION_DATETIME BETWEEN t.TRIP_START AND t.TRIP_END 
WHERE to_char(v.PERMIT) = t.PERMIT 
; 

編集:別の答えにコメントでは、OPは、構文エラーを修正した後、クエリは内部結合、左の代わりに結合を実行するようだと指摘しました。これはWHERE句によって発生します。それはOPがそれを追加の結合条件として意味していたようだ。 WHERE条件として、フィルタリングは結合が完了した後に実行され、外部結合によって追加された余分な行が除外されます。目的の結果を得るには、クエリは次のように記述する必要があります。

SELECT v.*, t.TRIP_JOIN 
FROM schA.VMS v LEFT JOIN schB.TRIP t 
    ON v.POSITION_DATETIME BETWEEN t.TRIP_START AND t.TRIP_END 
AND to_char(v.PERMIT) = t.PERMIT      ---- not WHERE 
; 
+0

ありがとうございます - 私は既にうまくいっているようですが、もっと詳細な答えを(私は確信しているように)(+ 1)感謝します。私はto_date()を削除しましたが、結果を変更するために*表示されませんでしたが、to_date()を使用しないとより速くなりました。 – Jordan

+1

パフォーマンスが向上したことは、TRIP_STARTとTRIP_ENDに索引があることを示唆しています(おそらくそうであるはずです)。関数呼び出しの中にそれらをラップすると、それらのインデックスの使用が妨げられます。条件を正しく記述すると、インデックスが使用されます。これはうれしかったです。 – mathguy

関連する問題