2010-11-24 13 views
0

2つのテーブル間の結合を行い、レコードがあるかどうかに基づいて列を選択するとします。私は同じフィールドの複数を持つことを避けようとしており、それらを単一の列に凝縮しようとしています。ような何か:NULLSと存在しないレコードを確認するSQL Caseステートメント

Select 
    id = (CASE WHEN a.id IS NULL THEN b.id ELSE a.id END), 
    name = (CASE WHEN a.name IS NULL THEN b.name ELSE a.name END) 
From Table1 a 
Left Join Table2 b 
On a.id = b.id 
Where a.id = @id 

私はレコードが存在する場合idTable1から移入するように、しかし、Table2から引っ張らない場合と思います。前のコードでは、の値がTable1に存在しないため、レコードが返されないので、私の質問はどのようなレコードが存在するかどうかをチェックする方法です。また、私がしようとしていることを達成するためのより良い方法を誰もが知っているなら、指導と建設的な批評に感謝します。

EDIT

COALESCEは私が達成しようとしている何のために働くように見えます。ちょうど私が働いているものに少し詳しい情報を与えて、私が最良の方法を使用しているかどうかについていくつかアドバイスをしたいと思います。

私は肥大化したテーブルTable2を持っています。私はこのシステム用の新しいWebアプリケーションを構築する作業をしていますが、完全なデータベース再設計を正当化することはできませんので、私は「オンザフライ」でそれをやろうとしています。私は、新しいテーブルTable1を作成しましたし、私は次の方法GetSelect)、SetUpdate)、AddInsert)、RemoveDelete)のためのストアドプロシージャを書いています。このように、私のコードでは、私は膨らんでいない単一のテーブルで作業しているように見えます。私のコードは単にSPメソッドの1つを呼び出し、ストアドプロシージャは古いテーブルと新しいテーブルの間のデータを処理します。私は現在Getメソッドで作業しており、Table1に存在しない場合は、古いテーブルTable2をレコードとしてチェックする必要があります。ここでの提案に おかげで私のクエリは、現在、次のようになります。

Select 
    id = coalesce(a.id, b.student_number), 
    first_name = coalesce(a.first_name, b.first_name), 
    last_name = coalesce(a.last_name, b.last_name), 
    //etc 
From Table1 a 
Full Outer Join Table2 b 
On a.id = b.student_number 
Where (a.id = @id Or b.student_number = @id) 

私が達成しようとしているものを、私はあれば任意のヒントや提案のために、経験豊富な群衆にそこにそれを投げるしたいためにこの作品これについてもっと良いやり方があります。

おかげ

答えて

1

私はあなたの問題は左結合をやってから来るかもしれない疑いがあります。

Select 
    id = coalesce(a.id, b.id), 
    name = coalesce(a.name, b.name) 
From Table1 a 
full outer Join Table2 b 
On a.id = b.id 
Where a.id = @id 
+0

+1不正な結合を使用していました。 – jon3laze

0

あなたのような何かを行うことができます:

選択IDを、a.idない(表2からのIDを選択)で UNIONは、IDを選択 表1のA、表2のB

から名前から名前

これは、table2の対応する一致をtable2のレコードに加えていないtable1のすべてのレコードを提供します。組合はその結果を組み合わせるだろう。

1
Select id = coalesce(a.id, b.id), 
    name = coalesce(a.name, b.name) 
From Table2 b 
Left Join Table1 a On a.id = b.id 
Where b.id = @id 

あなたのデータベースプラットフォームに依存する代わりにCOALESCEISNULLまたはCASEを使用する必要があります。

0

最初のCASE文では、a.idとb.idが常に同じ値になりますが、a.idには値があり、b.idにはLEFT JOINのためNULL値が生成されます。結果セットには、NULLのa.id値とNULLでないb.id値を持つ行はありません。この列にはa.idだけを使用できます。

2番目のCASE文では、どちらかまたは両方のテーブルに値のある列があります(値は異なる場合があります)。あなたは、これらの列の値を「凝縮」したいと言いました。そのためのSQL関数はCOALESCEある:

最初の非NULL値を返し
COALESCE(a.id, b.id) 

(a.idそれ以外b.id、NULLでない場合)。 2つのテーブルの異なる名前にあなたを紹介することはありません。

1

まず、あなたはそのためにcase文を必要としません:

Select ISNULL(a.id,b.id) AS id, ISNULL(a.name,b.name) AS name, 
From Table1 a 
Left Join Table2 b 
On a.id = b.id 
Where a.id = @id 

第二に、私は右のそれを取得する場合、idフィールドがNULLを含むことができ、その場合には、あなたがネジ止めされます。つまり、IDは行を識別する一意の値であり、nullの場合はその行を識別できません。

しかし、あなたが望むことは表1と表2からレコードを取得し、重複を避けるされている場合、それは重複を破棄するので、簡単なUNIONは、正常に動作します:

select id, name 
from Table1 
where id = @id 

union 

select id, name 
from Table2 
where id = @id 
+0

IDフィールドがNULLになることはありません。私が扱っているすべての実際の列を置くのではなく、単純にidとnameを例の列として入れます。私は、私が達成しようとしてきたことについて、より多くの情報で質問を更新しました。ご協力いただきありがとうございます。 – jon3laze

関連する問題