2012-02-01 4 views
2

ここの例よりも複雑ですが、特定のフィールドがデータセットに複数回表示されない行を返す必要があるクエリがあります。この例では1つの値が1回しか表示されない行のみに制限する

ACTIVITY_SK  STUDY_ACTIVITY_SK 
100    200 
101    201 
102    200 
100    203 

データセットに二回ACTIVITY_SK表示されますので、私は返される100の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

こんにちは、おかげで...私は私がすることによってグループ化しています何かのカウントを行うことができるとは思いませんでしたか?私は効果的に同じクエリを2回実行することを避けることができないように見える、aとbの間の結合は両方のクエリで行われる必要があります。 – user1183688

+0

できます。一般的に私はCOUNT(*)を使用しません、私はいつもCOUNT(PK_COLUMN)を試しています。なぜなら、PKは決してヌル値を持たず、オプティマイザはその列のインデックスを使うことができるからです。 – Mithrandir

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がアクティビティテーブルから一意の識別子を指します)

関連する問題