Sql - 有一个需要过滤掉重复项的大查询

时间:2017-12-08 19:56:30

标签: sql oracle

我有一个大规模的查询,它连接了大约70个表并返回超过200列:

SELECT TABLEA.ID, TABLEB.ID, TABLEC.ID  ...
FROM TABLEA LEFT JOIN TABLEB ON TABLEA.ID = TABLE.FID LEFT JOIN TABLEC ON TABLEB.ID = TABLEC.FID ...
WHERE [some conditions]

此结果有一个应该返回的唯一主列,即TABLEA.ID。列中的所有值都应该是唯一的,但由于数据收集不良,因此存在一些重复。所以我有一些ID是重复的,他们有其他列具有不同的值。从这些重复中我知道我需要抓取哪些特定行以及我可以丢弃的重复项(例如,抓住TABLEA.ID = 9999和TABLEZ.SOMECOLUMN =' JOHN DOE')的行。

所以最终的结果集看起来像这样:

TABLEA.ID | TABLEB.ID | TABLEZ.SOMECOLUMN .....
     1         fjash       BOB
     2         dfd         BOB
     3         34g         JOHN
     3         vfg         KIM
     3         vsd         OBI-WAN
     4         vgsdfg      NICK
     4         fg          HA
     5         hggh        HAHA

从此我知道我需要过滤哪些重复以获得这样的内容:

TABLEA.ID | TABLEB.ID | TABLEZ.SOMECOLUMN .....
     1         fjash       BOB
     2         dfd         BOB
     3         34g         JOHN
     4         vgsdfg      NICK
     5         hggh        HAHA

我认为这很容易,因为我会在where子句中简单地过滤它们,但事实证明它比我想象的更复杂。

 SELECT TABLEA.ID, TABLEB.ID, TABLEC.ID  ...
    FROM TABLEA LEFT JOIN TABLEB ON TABLEA.ID = TABLE.FID LEFT JOIN TABLEC ON TABLEB.ID = TABLEC.FID ...
    WHERE [some conditions]
    AND (TABLEA.ID = 9999 AND TABLEZ.SOMECOLUMN = 'JOHN DOE')

但这只会返回一行。我尝试否定它尝试了另一种组合:

AND (TABLEA.ID = 9999 AND TABLEZ.SOMECOLUMN <> 'OTHER VALUE OTHER THAN JOE DOE')

但这也行不通。

1 个答案:

答案 0 :(得分:0)

好的,我正在尝试用同一种语言帮助伪代码。请尝试联系。

尝试使用row_number over id by partition(唯一)并过滤row_number 1值: 请尝试避免ID的首选值,因为您希望此列在输出数据集中是唯一的。

尝试:

SELECT TABLEA.ID, TABLEB.ID, TABLEC.ID  ...
FROM
    (SELECT TABLEA.ID, TABLEB.ID, TABLEC.ID  ...
       ,ROW_NUMBER() OVER(PARTITION BY TABLEA.ID 
                     ORDER BY CASE WHEN TABLEX.SOMECOLUMN = 'Some preferred value' THEN 0 ELSE 1 END,
                              CASE WHEN TABLEZ.SOMEOTHERCOL='Some other preferred value' THEN 0 ELSE 1 END, 
                              ROWNUM) RN
        FROM TABLEA LEFT JOIN TABLEB ON TABLEA.ID = TABLE.FID LEFT JOIN TABLEC  
        ON TABLEB.ID = TABLEC.FID ...
        WHERE [some conditions])
WHERE RN=1;