2012-02-01 73 views
2

我有一個比這裏的示例更復雜的查詢,但它只需返回某些字段在數據集中不會出現多次的行。將結果限制爲只有一個值只出現一次的行

ACTIVITY_SK  STUDY_ACTIVITY_SK 
100    200 
101    201 
102    200 
100    203 

在這個例子中,我不想與100的ACTIVITY_SK任何記錄返回,因爲ACTIVITY_SK數據集中出現兩次。

該數據是一個映射表,並在許多連接中使用,但是像這樣的多個記錄意味着數據質量問題,因此我需要將它們從結果中簡單地刪除,而不是在其他地方導致錯誤的連接。

SELECT 
    A.ACTIVITY_SK, 
    A.STATUS, 
    B.STUDY_ACTIVITY_SK, 
    B.NAME, 
    B.PROJECT 
FROM 
    ACTIVITY A, 
    PROJECT B 
WHERE 
    A.ACTIVITY_SK = B.STUDY_ACTIVITY_SK 

我試過這樣的事情:

SELECT 
    A.ACTIVITY_SK, 
    A.STATUS, 
    B.STUDY_ACTIVITY_SK, 
    B.NAME, 
    B.PROJECT 
FROM 
    ACTIVITY A, 
    PROJECT B 
WHERE 
    A.ACTIVITY_SK = B.STUDY_ACTIVITY_SK 
WHERE A.ACTIVITY_SK NOT IN 
(

    SELECT 
    A.ACTIVITY_SK, 
    COUNT(*) 
    FROM 
     ACTIVITY A, 
     PROJECT B 
    WHERE 
    A.ACTIVITY_SK = B.STUDY_ACTIVITY_SK 
    GROUP BY A.ACTIVITY_SK 
    HAVING COUNT(*) > 1 

) 

但是,必須有這樣做的更便宜的方式...

回答

4

像這樣的東西可能是一個有點「便宜」到運行:

SELECT 
    A.ACTIVITY_SK, 
    A.STATUS, 
    B.STUDY_ACTIVITY_SK, 
    B.NAME, 
    B.PROJECT 
PROJECT B INNER JOIN 
    (SELECT 
     ACTIVITY_SK, 
     MIN(STATUS) STATUS, 
    FROM 
     ACTIVITY 
    GROUP BY ACTIVITY_SK 
    HAVING COUNT(ACTIVITY_SK) = 1) A 
ON A.ACTIVITY_SK = B.STUDY_ACTIVITY_SK 
+0

您好,感謝......沒想到我能做到的事情,我通過分組計數?看起來我無法避免兩次有效地運行相同的查詢,a和b之間的連接需要在兩個查詢中進行,因爲這是創建重複項的連接。 – user1183688 2012-02-01 21:18:32

+0

你可以。通常我不使用COUNT(*),我總是嘗試COUNT(PK_COLUMN),因爲PK從來沒有空值,優化器可以在該列上使用索引。 – Mithrandir 2012-02-01 21:22:16

1

另一種選擇:

select * from (
    SELECT 
    A.ACTIVITY_SK, 
    A.STATUS, 
    B.STUDY_ACTIVITY_SK, 
    B.NAME, 
    B.PROJECT, 
    count(distinct a.pk) over (partition by a.activity_sk) AS c 
    FROM 
    ACTIVITY A, 
    PROJECT B 
    WHERE 
    A.ACTIVITY_SK = B.STUDY_ACTIVITY_SK 
) where c = 1; 

(其中a.pk是指從活動表中的唯一標識符)