2016-08-18 7 views
3

私は本質的にtableBの情報に基づいてtableAの単一レコードに参加しようとしています。元の結合条件で複数の結果が得られたら、さらに追加してクエリを再実行します。結果が得られない場合は、何も転送されません。例:a.FRST_NM = b.FRST_NMを検索します。結果が1つの場合は、レコードを引き出します。複数ある場合はLAST_NMを追加し、結果が1つの場合はそのレコードをプルします。私が1つのレコードを得るまで、そうします。一度に1つずつすることはできますが、これは1回のパスにつき2〜3回発生します。検索を実行してメンバーを特定する

これは、1つのテーブルには入力されていないフィールドがあるためです。 FROMステートメント全体を書き直さずに結合条件を追加する方法や、結果が1つしかない場合にのみレコードをプルする方法はわかりません。

IF(CONDITION_1 from JOIN_1) = 1 result THEN a.field_1 = b.field_1 and a.field_2 = b.field_2 

IF (CONDITION_1 from JOIN_1) > 1 result THEN (additional joining conditions + JOIN_1) as JOIN_1a 

ELSE IF(CONDITION_1 from JOIN_1a) = 1 result then a.field_1 = b.field_1 and a.field_2 = b.field_2 

IF(CONDITION_1 from JOIN_1) = 0 results then NO MOVE 

--(Repeat with different tables and joining conditions)-- 

答えて

1

Hmmm。 1つの方法は、1つのフィールドに参加し、他のフィールドに基づいて優先順位を付けることです。もう1つはleft joinです。だから、基本的にはこれが一致し、この場合、あなたが上のベースたい正確なレコードを選択することができますリストからのみFirst_NM基準、その後構築し、オーダーの検索を行い

select t1.*, coalesce(t2a.col, t2b.col, t2c.col) as col 
from t1 left join 
    t2 t2a 
    on t1.col1 = t2a.col1 and t1.col2 = t2a.col2 and t1.col3 = t2a.col3 left join 
    t2 t2b 
    on t1.col1 = t2b.col1 and t1.col2 = t2b.col2 and t2b.col1 is null left join 
    t2 t2c 
    on t1.col1 = t2c.col1 and t2b.col1 is null; 
1
SELECT * 
FROM (
    SELECT 
     * 
     ,CASE WHEN a.LAST_NM = b.LAST_NM THEN 'matched' ELSE 'not matched' END LastNameMatchedExample 
     ,ROW_NUMBER() OVER (PARTITION BY 1 ORDER BY 
       CASE 
        WHEN a.LAST_NM = b.LAST_NM AND a.Field1 = b.Field1 AND a.Field2 = b.Field2 AND a.Field3 = b.Field3 THEN 0 
        WHEN a.LAST_NM = b.LAST_NM AND a.Field1 = b.Field1 AND a.Field2 = b.Field2 THEN 1 
        WHEN a.LAST_NM = b.LAST_NM AND a.Field1 = b.Field1 THEN 2 
        WHEN a.LAST_NM = b.LAST_NM THEN 3 
        ELSE 4 
       END 
      ) as RowNumber 
    FROM 
     TableA a 
     INNER JOIN TableB b 
     ON a.FIRST_NM = b.FIRST_NM 
    ) results 
WHERE 
    results.RowNumber = 1 

:それは次のようになります。一致し、これは一致します。したがって、返されるレコードの数に関係なく、最初の結果が得られます。すべてが同じ2つのテーブルから来ているので、必要な量のカラムを常に維持する必要があります。一致するものがない場合は、NULLを値にするためにCASE STATEMENTSを使用できます。

以下は、フィールドの優先順位ですが、それは他のフィールドと一致するOR条件を好んで処理します。したがって、この例では、マッチなどの一致の存在をソートし、すべてのステートメントを処理します。 LAST_NMの一致は発生しませんが、1つのレコードでフィールド1の一致が発生し、別のフィールドで一致しない場合は、フィールド1がより高い結果に一致します。

SELECT * 
FROM (
    SELECT 
     * 
     ,CASE WHEN a.LAST_NM = b.LAST_NM THEN 'matched' ELSE 'not matched' END LastNameMatchedExample 
     ,ROW_NUMBER() OVER (PARTITION BY 1 ORDER BY 
       CASE WHEN a.LAST_NM = b.LAST_NM THEN 0 ELSE 1 END 
       ,CASE WHEN a.Field1 = b.Field1 THEN 0 ELSE 1 END 
       ,CASE WHEN a.Field2 = b.Field2 THEN 0 ELSE 1 END 
       ,CASE WHEN a.Field3 = b.Field3 THEN 0 ELSE 1 END 
      ) 
    FROM 
     TableA a 
     INNER JOIN TableB b 
     ON a.FIRST_NM = b.FIRST_NM 
    ) results 
WHERE 
    results.RowNumber = 1 
+0

したがって、結合条件を変更する代わりに、代わりにCASE式を作成しますか?それは実際に簡単に聞こえる。特に、後のパスではいくつかのテーブルが削除され、別のテーブルが追加されるためです。 –

+0

これは、検索するすべてのテーブルが最初にLEFT JOINとして結合されていることを前提としています。次に、case文に基づいて優先順位を設定するrow_number()優先順位を作成して、必要なレコードを選択します。しかし、あなたはまだテーブルのすべてを最初に結合しなければなりません... – Matt

+0

これは最初のパスで動作しますが、後のパスでテーブルが削除され、> 1または= 0の結果が出たら実行するために異なるテーブルに参加します。 –

関連する問題