私は3つのテーブルを持っています(ここで簡略化されています):
recipients: recipientId, isGroup
users: userId, first name, last name
groups: groupid, groupname
受信者がユーザーの場合は名/姓を取得し、受信者がグループの場合はグループ名を取得したい。受信者がどちらでもない(つまり、削除された/存在しないグループ)可能性があるので、その場合は何も返しません。
だからこれは私がしたことです:
select u.first_name, u.last_name, g.groupname, r.isGroup
from recipients r
left join users u on u.userid = r.recipientId
left join groups g on g.groupid = r.recipientId
where r.isGroup IS NULL or g.groupname IS NOT NULL
上記のクエリは期待される結果を返していません。私はこれを取り戻しています:
adam, smith, null, null
yolanda, smith, null, null
null, null, members, 1
null, null, null, 1
明らかにグループ名がなく(たとえば、groupnameがNULL)、r.IsGroup = 1であるため、最後の行は予期しないものです。
私がこれをするとき:
select u.first_name, u.last_name, g.groupname, r.isGroup
from recipients r
left join users u on u.userid = r.recipientId
left join groups g on g.groupid = r.recipientId
where r.isGroup IS NULL
期待どおりの結果が得られます:
adam, smith, null, null
yolanda, smith, null, null
そして私がこれをするとき:
select u.first_name, u.last_name, g.groupname, r.isGroup
from recipients r
left join users u on u.userid = r.recipientId
left join groups g on g.groupid = r.recipientId
where g.groupname IS NOT NULL
期待どおりの結果が得られます:
null, null, members, 1
2つのwhere句をORと組み合わせた場合にのみ、追加の行を取得できます。
ここで、クエリを(IS NULLからISNULLに変更)に変更すると、次のようになります。
select u.first_name, u.last_name, g.groupname, r.isGroup
from recipients r
left join users u on u.userid = r.recipientId
left join groups g on g.groupid = r.recipientId
where r.isGroup IS NULL or ISNULL(g.groupname, null) IS NOT NULL
期待どおりの結果が得られます。
adam, smith, null, null
yolanda, smith, null, null
null, null, members, 1
実際、where句を変更する必要はありません。次のクエリも同様に機能し、上記の期待される結果が得られます。
select u.first_name, u.last_name, ISNULL(g.groupname,null), r.isGroup
from recipients r
left join users u on u.userid = r.recipientId
left join groups g on g.groupid = r.recipientId
where r.isGroup IS NULL or g.groupname IS NOT NULL
だから、問題は、なぜですか?SELECTステートメントにISNULLを入れると、WHERE句の動作が変わるのはなぜですか?なぜそれがまったく違いを生むのですか?最初のクエリが機能しないのはなぜですか?ORを追加した場合にのみ機能しないのはなぜですか?ORを追加しないと壊れないのはなぜですか?
前もって感謝します。
MS SQLServer2008を使用しています。
編集:タイプミスを修正し、質問を明確にしました