0

我有一个案例,我需要像下面的查询一样进行多个连接(查找)。给出了示例场景。

我有大约 200 个 CAT_CODE。我想了几个解决方案,我把它列为案例。有没有什么不同的方法来编写一个 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来完成。我们需要使用查找来完成这项工作。

场景一:

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

我不认为,这将是正确的做法。我们有 200 个代码,我们不能使用 200 个查找。在ETL(Datastage,Talend,BODS)中是否有更好的方法来处理具有更好的性能?

场景二:

像下面这样旋转 PRIM(将 CAT1_CODE、CAT2_CODE、CAT3_CODE 列转换为行)并进行一次查找。但是旋转需要很长时间,因为我们有大约 6 亿和 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。提前致谢。

4

1 回答 1

1

您可以使用LATERAL 关键字来执行您正在寻找的魔法。

以下代码可能会有所帮助:

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
于 2016-04-01T14:38:10.110 回答