2011-11-11 24 views
3
Student Table 

SID Name 
1  A 
2  B 
3  C 

Marks Table 

id mark subject 
1 50 physics 
2 40 biology 
1 50 chemistry 
3 30 mathematics 



SELECT distinct(std.id),std.name,m.mark, row_number() over() as rownum FROM 

student std JOIN marks m ON std.id=m.id AND m.mark=50 

この結果はdisticntを使用した後でも2倍です。もし私がrow_number()over()をrownumとしてうまく動作させてしまうと、私の予想される結果には1つのA.しかありません。なぜこれが起こっているのですか?解決する方法。 DB2を使用しているAM!重複を回避する方法2つのテーブルを結合する

+0

物理学と化学の両方でAのマークを必要としない場合、学生とマークに参加する点は何ですか? – sceaj

+0

私はちょうど少なくとも1つのサブジェクトで50を得た学生を欲しがります – zod

答えて

5

ID = 1マーク= 50とマーク表の2行は一つだけにしたい場合は、学生のテーブルの行ごとに出力の2行... を取得しますので、あなたがしなければならない。..あります

SELECT std.id, std.name, m.mark, row_number() 
    over() as rownum 
FROM student std 
    JOIN marks m 
     ON m.id=std.id AND m.mark=50 
Group By std.id, std.name, m.mark 
+0

結合に述語を入れない(ほぼ)! – orbfish

+1

常に結合述部を結合に入れます。 where節述部は、結果セット全体が生成されるまで評価されないため、不要な行が処理中に持ち越され、特定の外部結合シナリオではwhere節に述部を置くと不正な結果が生成されます。最後に、ジョインにジョイン述語を置くと、最後に一緒になるのではなく、近くにテーブルが置かれます。これにより、クエリーに明快さが加わります。 –

+0

また、同じ表に複数回結合したい場合もありますが、結合ごとにDIFFERENT述部を使用することもできます。どのようにWhere節でそれを行うつもりですか? –

3

ことでグループが今、あなたのようにあなたの質問を明確にしたこと:

私は、少なくとも一つの対象に50のマークが付いたすべての学生を見つけたいです。私はクエリを使用します:

SELECT student.id, '50' 
FROM student 
WHERE EXISTS (SELECT 1 FROM marks WHERE marks.id = student.id AND marks.mark = 50) 

これはまた、条件を変更する柔軟性を与えます。 50以下の少なくとも1つのマーク。

+0

+1 EXISTS(半結合)はあなたが本当にやりたいことです。余分なデータをすべて必要としないため、完全結合は必要ありません。このクエリは、完全結合の余分な作業を行うのと比べて効率的です。そして、データセットを最初に欲しかったものだけにトリムするために、さらに余分な作業を行います。 –

+0

+1はWHERE EXISTSを使用していますが、彼のrownumの列は忘れています。 – orbfish

+0

@orbfish私はOPが 'row_number()over()'で何をしようとしているのか本当に分かりません。おそらくあなたは明確にすることができますか? – sceaj

1

チャールズの答えに似ていますが、WHERE句に常に述語(mark = 50)を入れたいので、結合する前にフィルタリングしています。これが単なる宿題であれば問題ではないかもしれませんが、実際のデータにヒットした場合はこれを覚えておきたいと思います。

SELECT std.sid, 
     std.name, 
     m.mark, 
     row_number() over() AS rownum 
FROM student std 
     JOIN marks m 
     ON std.sid=m.id 
WHERE m.mark=50 
GROUP BY std.sid, std.name, m.mark 
+0

ほとんどのクエリオプティマイザは、通常、句の配置に関係なくフィルタを適用するのに最適な時間を見つけることができます。これはDB2のクールークですか? –

+0

@M_M - いいえ - DB2は(少なくともiSeries上では)同じExplainプランを生成するように見えますが、2つのクエリを同等のものとみなしているようです(同じアクセスパスを使用)。少なくともこのような単純な例では、 @All - 'WHERE'節と' JOIN'節の間に条件を置くことは常に同じ結果を返さないでしょう(これは 'LEFT'と/または' EXCEPTION'結合を使うときにはほとんど関係します)ので、条件はパフォーマンスの理由からではなく、正しい結果を生成します(DB2オプティマイザもかなり良いです)。 –

+0

@M_M - 私はOracleに詳しい。ときどきそれを把握することもありますが、時にはSQLを使ってあなたが言うことを本当に意味し、永遠に続くことになります。 – orbfish

関連する問題