2016-04-01 8 views
0

私は、以下のような複数の結合(ルックアップ)を行う必要があるケースがあります。サンプルシナリオが与えられました。複数のルックアップの回避とパフォーマンスの向上

私は約200のCAT_CODEを持っています。私はいくつかのソリューションを考え、cases.Isとしてより良いパフォーマンスを持つためにSQLクエリを書くための方法は何ですか? ETLツールでのより良いアプローチ

プライマリ表(PRIM):

NUM  CAT1_CODE CAT2_CODE CAT3_CODE 
A   1   y   q  
B   2   e   a  
C   3   s   z  

セカンダリ表(LOV):

CATEGORY COLUMN_LKP  EXT_CODE 
CAT1_CODE  1    AB 
CAT1_CODE  2    CD 
CAT1_CODE  3    HI 
CAT2_CODE  y    JL 
CAT2_CODE  e    QD 
CAT2_CODE  s    AH 
CAT3_CODE  q    CD 
CAT3_CODE  a    MS 
CAT3_CODE  z    EJ 

CASE-1:SQLを通じて:

私が書かれていますこのタスクを達成するための簡単なクエリです。あなたはこれが正しいアプローチだろうと思いますか?他の方法、このクエリを改善するには?今、私はOracleとPostgresの両方を使用しています。

SELECT 
NUM, 
(SELECT EXT_CODE FROM TEST_LOV 
WHERE CATEGRY='CAT1_CODE' AND COLUMN_LKP=A.CAT1_CODE) CAT1, 
(SELECT EXT_CODE FROM TEST_LOV 
WHERE CATEGRY='CAT2_CODE' AND COLUMN_LKP=A.CAT2_CODE) CAT2, 
(SELECT EXT_CODE FROM TEST_LOV 
WHERE CATEGRY='CAT3_CODE' AND COLUMN_LKP=A.CAT3_CODE) CAT3 
FROM 
TEST_PRIM A 

要求出力:

NUM CAT1 CAT2 CAT3 
A AB  JL  CD 
B CD  QD  MS 
C HI  AH  EJ 

事例2:ETL:

同じ場合は、ETLを介して達成することができます。そのためにルックアップを使用する必要があります。

シナリオ-1:私は考えていない

 LOV(CAT1_CODE) LOV(CAT2_CODE) LOV(CAT3_CODE) 
      |    |     | 
      |    |     | 
PRIM---->LOOKUP---------->LOOKUP------------>LOOKUP-------->TARGET 

、正しいアプローチだろう。 200個のコードがあり、200個のルックアップを使用することはできません。優れたパフォーマンスを備えたETL(Datastage、Talend、BODS)を扱うためのより良いアプローチはありますか?

シナリオ-2:

ピボットPRIM以下のように(行の中でCAT1_CODE、CAT2_CODE、CAT3_CODE列を変換)、我々は6億周りのデータを持っているので、多くの時間がかかります1つのlookup.Butの旋回を行うと、 200列。

NUM  CATGRY   CODE 
A  CAT1_CODE   1 
A  CAT1_CODE   y 
A  CAT1_CODE   q 
B  CAT2_CODE   2 
B  CAT2_CODE   e 
B  CAT2_CODE   a 
C  CAT3_CODE   3 
C  CAT3_CODE   s 
C  CAT3_CODE   z 

このアプローチを処理する最善の方法を教えてください。これは、ETLまたはSQLを使用して行うことができます。前もって感謝します。

+0

適切にあなたの質問にタグを付けてください。どのデータベースを使用していますか? PostgresまたはOracle(または何か他のもの)? –

+0

このケースは、oracleとpostgresの両方で実装する必要があります(別のアプリケーション) – Raja

答えて

1

LATERALkeywordを使用すると、探している魔法を実行できます。

次のコードは、助けることができる:

SELECT 
    NUM, 
    MAX(ext_code) FILTER (WHERE c.CATEGORY='CAT1_CODE') AS CAT1, 
    MAX(ext_code) FILTER (WHERE c.CATEGORY='CAT2_CODE') AS CAT2, 
    MAX(ext_code) FILTER (WHERE c.CATEGORY='CAT3_CODE') AS CAT3 
FROM TEST_PRIM a 
    CROSS JOIN LATERAL (
    SELECT * 
    FROM TEST_LOV b 
    WHERE 
     (a.CAT1_CODE=b.COLUMN_LKP AND B.CATEGORY = 'CAT1_CODE') 
     OR (a.CAT2_CODE=b.COLUMN_LKP AND B.CATEGORY = 'CAT2_CODE') 
     OR (a.CAT3_CODE=b.COLUMN_LKP AND B.CATEGORY = 'CAT3_CODE') 
    ) c 
GROUP BY NUM 
ORDER BY NUM; 

出力

num | cat1 | cat2 | cat3 
-----+------+------+------ 
A | AB | JL | CD 
B | CD | QD | MS 
C | HI | AH | EJ 
+0

ありがとうRobin。しかし、あなたのコードはn個の列にクエリを作成するのに役立ちます。しかし、私の質問は異なっています。私のクエリはより良いパフォーマンスを提供しますか?それをもっと速くするために、 – Raja

+0

必須のSQLで回答を更新しました。あなたが探している機能は、Postgres v9.4 +でサポートされている 'LATERAL'クエリと呼ばれます。 9 –

+0

LATERALの詳細はこちら(http://www.depesz.com/2013/07/23/waiting-for-9-4-implement-the-filter-clause-for-aggregate-function-calls/) –

関連する問題