2012-05-09 16 views
1

私は、この時点で(この時点で、その列でどのように/どの値が使用されているかを変更することはできません)同じ値。したがって、最初の表の列の値によっては、2番目の表の特定の値を結合/選択する必要があります。ここで私が何をしようとしています何の(明らかに動作しません)例です。コメントテーブル内の対応するレコードが存在する場合、外部結合のIF/CASE

SELECT Alert.*, Comments.Comment FROM 
Alert 
LEFT OUTER JOIN Comments ON Comments.ObjectId = Alert.ObjectId AND 
CASE 
WHEN Alert.ObjectType = 'U' THEN Comments.ObjectType = 'USER' 
WHEN Alert.ObjectType = 'E' THEN Comments.ObjectType = 'EVENT' 
END CASE 

は、だから私は警告テーブルからすべてをしたいがして、私はそれらをしたいです、あまりにも。しかし、適切な/一致するObjectTypeに対してのみ。

私はCASEとIFの両方を使用してこれを試しましたが、動作させることができません。このようなことは可能でしょうか?

答えて

4

CASE文は操作を行わないに、返り値になっています。

最後のEND CASEもちょうどENDに変更してください。

戻り値を使用して、結合条件と比較します。

試してみてください。

SELECT Alert.*, Comments.Comment FROM 
Alert 
LEFT OUTER JOIN Comments ON Comments.ObjectId = Alert.ObjectId AND 
Comments.ObjectType = 
CASE Alert.ObjectType 
WHEN 'U' THEN 'USER' 
WHEN 'E' THEN 'EVENT' 
END 
+0

OPの元のクエリでは、*値を返しています(具体的にはブール値を 'ON'節に直接返しています)。より簡潔です)。私が理解するのを助けることができますか? :) – eggyal

+0

@eggyal、私はすべての細部の専門家ではありませんが、ブール式はすべての状況で期待されるように機能しません。 'a = b'を条件式ロジック、if文などで使うことができるブール式ですが、どこでも使用または割り当て可能なブール値を返しません。 –

+0

これは機能しません。私は取得していますエラーは、次のとおりです。 「あなたはあなたのSQL構文でエラーが発生している。近くに 『CASE』を使用する権利構文 のためのMySQLサーバのバージョンに対応 ことを手動で確認し、」 を適切な構文ということですか? 私はv5を実行しています。5 – Christoph

0

理由だけではない:

SELECT Alert.*, Comments.Comment FROM 
Alert 
LEFT OUTER JOIN Comments ON Comments.ObjectId = Alert.ObjectId AND 
Alert.ObjectType = LEFT(Comments.ObjectType, 1); 

それはずっと簡単そうです...あなたのコメントに基づいて

EDIT

、それはそうですすべての '一致する'値が同じ文字で始まるわけではありません。この場合、AlertType char(1)とCommentType varchar(50)の列を持つ中間テーブルを設計することをお勧めします。 TypeIdの各組み合わせをU、Userのように挿入します。 E、イベント;あなたはあなたのSQLを読むために変更することができます

SELECT Alert.*, Comments.Comment FROM 
Alert 
LEFT OUTER JOIN Intermediate i on Alert.ObjectType = i.AlertType 
LEFT OUTER JOIN Comments ON Comments.ObjectId = Alert.ObjectId AND 
Comments.ObjectType = i.CommentType; 
+0

1つのテーブル内にオブジェクトタイプが1つの文字( "U"、 "E"など)であるが、他のテーブルでは完全な単語であり、それらの単語のいくつかは同じ文字で始まります。最善の考え方ではなく、私は元のデザイナーの頭に戻って何かを感じることができるように多くを与えます。お返事をありがとうございます! – Christoph

+0

LEFT(x、1)で結合するなどの戦略は、フィールドxの任意のインデックスを難読化します。これは、プログラム的な利便性のための「簡素化」が重要なパフォーマンスを犠牲にして行われることを意味する。中間結合(またはそれをシミュレートするCASE WHENの使用)は、*大幅に*優れたオプションです。 – MatBailie

+0

@Dems:そうです、LEFT()オプションはパフォーマンスを低下させます。一方、単語の最初の文字を使用しているように、索引を使用できるようにする必要があります。これは、RIGHT()関数の場合には当てはまりません。第2に、この質問では索引は参照されていないため、この列が索引付けされていると仮定することは時期尚早です。最後に、質問は2行しか扱わなかったので、ここでのパフォーマンスは大きな懸念事項ではないかもしれませんが、質問の一部ではありません。 – therealmitchconnors

0

私はこれをUNIONで処理することをお勧めします。 1つの組合では、他にユーザーのコメントイベントコメントの参加:

SELECT Alert.*, userComments.Comment 
FROM alert 
LEFT OUTER JOIN comments usercomments ON userComments.ObjectId = Alert.ObjectId AND usercomments.objecttype='USER' 
WHERE alert.objecttype = 'U' 
UNION 
SELECT Alert.*, eventComments.Comment 
FROM alert 
LEFT OUTER JOIN comments eventcomments ON eventComments.ObjectId = Alert.ObjectId AND eventcomments.objecttype='EVENT' 
WHERE alert.objecttype = 'E' 

あなたは、彼らが道私はそれらをエイリアスする必要はありません - それだけで可読性に役立ちます。

+0

これは、新しいObjectIdが追加されるたびに新しいUNION文を追加する必要があります。 – therealmitchconnors

+0

@therealmitchconnors - 非常に良い点。 –