NULL を比較すると UNKNOWN になります。
NULL 比較検索条件
NULL 値
create table [test] ( id int identity(1, 1) primary key, name1 char(5), name2 char(5) ) go insert into [test] ([name1], [name2]) values ( 'AAAAA', 'AAAAA' ), ( 'AAAAA', 'BBBBB' ), ( 'AAAAA', null ), ( null, 'AAAAA' ), ( null, null ) go
なデータがあって、[name1] と [name2] が異なるデータを取りたい時に、下のようなクエリを書いたとします。
select [id] from [test] where [name1] <> [name2]
Java や .NET だと、これで取れるでしょうが、SQL ではダメです。
id 3, 4 のデータが取れません。[name1] <> [name2] null は is null や is not null でないと比較出来ません。
もちろん次のクエリでもダメです。
select [id] from [test] where not ([name1] = [name2])
null が混じった "=" や "<>" は UNKNOWN になり、not UNKNOWN は UNKNOWN になるので、これまた行が返ってきません。
うっかり、null = 〜 が false になると勘違いしていると、ハマるかもしれませんね。*1
正しくは、こんなクエリ
select [id] from [test] where [name1] <> [name2] or ([name1] is null and [name2] is not null) or ([name1] is not null and [name2] is null)
以下、サンプルクエリ
create table [test] ( id int identity(1, 1) primary key, name1 char(5), name2 char(5) ) go insert into [test] ([name1], [name2]) values ( 'AAAAA', 'AAAAA' ), ( 'AAAAA', 'BBBBB' ), ( 'AAAAA', null ), ( null, 'AAAAA' ), ( null, null ) go select [id] from [test] where [name1] <> [name2] go select [id] from [test] where not ([name1] = [name2]) go select [id] from [test] where [name1] <> [name2] or ([name1] is null and [name2] is not null) or ([name1] is not null and [name2] is null) go drop table [test]
.NET や Java(Groovy) の場合
.NET
var list = new List<dynamic>() { new { Id = 1, Name1 = "AAAAA", Name2 = "AAAAA" }, new { Id = 2, Name1 = "AAAAA", Name2 = "BBBBB" }, new { Id = 3, Name1 = "AAAAA", Name2 = (String)null }, new { Id = 4, Name1 = (String)null, Name2 = "AAAAA" }, new { Id = 5, Name1 = (String)null, Name2 = (String)null }, }; list.Where(m => m.Name1 != m.Name2) .ToList().ForEach(m => Console.WriteLine((int)m.Id));
Groovy
def list = [ [id:1, name1:"AAAAA", name2:"AAAAA"], [id:2, name1:"AAAAA", name2:"BBBBB"], [id:3, name1:"AAAAA", name2:null], [id:4, name1:null, name2:"AAAAA"], [id:5, name1:null, name2:null], ] list.each { if (it.name1 != it.name2) { println it.id } }
*1:一瞬悩んだ…