2016-12-30 21 views
2

私は単純な2つの列テーブルを持っています。たとえば、次のデータを使用してデータを構築することができます。SQLで重複するサブクエリーを避ける最適な方法

CREATE TABLE Duplicates 
    (assignmentid varchar(5), questionid varchar(5)); 

INSERT INTO Duplicates 
    (assignmentid, questionid) 
VALUES 
    ('aaaaa', '11111'), 
    ('aaaaa', '22222'), 
    ('bbbbb', '22222'), 
    ('bbbbb', '33333'), 
    ('bbbbb', '33333'); 

同じ2つの行があります。複数の割り当てに表示される質問もあります。後者は有効なシナリオです。複数の課題の一部であるすべての質問のクエリを取得しようとしています。だから私の所望の出力は次のようになります。

aaaaa, 22222 
    bbbbb, 22222 

私はこれを取得することができた。この結果を:

SELECT main.questionid, sub.assignmentid 
FROM (
    SELECT questionid, count(assignmentid) AS AssignmentCount 
    FROM ( 
     SELECT DISTINCT questionid, assignmentid 
     FROM Duplicates 
    ) sub 
    GROUP BY questionid 
    HAVING AssignmentCount > 1 
) main 
INNER JOIN (
    SELECT DISTINCT questionid, assignmentid 
    FROM Duplicates 
) sub ON main.questionid = sub.questionid; 

あなたはDISTINCTサブクエリは二回繰り返されている見ることができるように。私はWITHコマンドを使用してこれを避けることができますが、これは必ずしもサブクエリが一度だけ実行されるというわけではありません。だから、今私はStackOverflowで、誰かがこのクエリを実行するためのより効率的な方法を知っているかどうか尋ねる。

+0

CTE(with)クエリ**は一度実行されます**。 –

+0

@a_horse_with_no_name CTEのコメントを拡大してください。私は、CTEをビュー(一時表と比較して)として扱うべきだと考えました。つまり、ビューが使用されるたびに、呼び出しが基礎となる表に繰り返されます。おそらく私は誤解したでしょう。ここで私が参照した別のstackoverflowページへのリンクです: Kumar

答えて

0

あなたはにそれを簡素化することができます:サブクエリはもっと​​して1 assignmentidに割り当てられているすべてのquestionidsを返し

select * 
from duplicates 
where questionid in (select questionid 
        from duplicates 
        group by questionid 
        having count(distinct assignmentid) > 1); 

0

ウィンドウ機能を使用してください。あなたはcount(distinct)せずにこれを行うことができます

が、それは1つの余分なサブクエリを必要とします:

select distinct answerid, questionid 
from (select d.*, 
      count(distinct answerid) over (partition by questionid) as cntd, 
      count(*) over (partition by questionid) as cnt 
     from duplicates d 
    ) d 
where cntd <> cnt; 

EDIT:一つの方法は、個別の回答の数に対する回答の数を比較することである

select distinct answerid, questionid 
from (select d.*, 
      count((seqnum = 1)::int) over (partition by questionid) as cntd, 
      count(*) over (partition by questionid) as cnt 
     from (select d.*, 
        row_number() over (partition by questionid, answerid order by questionid) as seqnum 
      from duplicates d 
      ) d 
    ) d 
where cntd <> cnt; 

この個別の計算に行番号を使用します。

+0

残念ながら、Postgresウィンドウ内で 'distinct'をサポートしていません –

+0

@a_horse_with_no_name。 。 。ありがとうございました。私は、SQL Serverがこの欠陥を持つ唯一のデータベースではないことを便利に忘れています。 –

関連する問題