2010-03-06 114 views
15
CREATE TABLE `mycompare` (
    `name` varchar(100) default NULL, 
    `fname` varchar(100) default NULL, 
    `mname` varchar(100) default NULL, 
    `lname` varchar(100) default NULL 
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 

INSERT INTO `mycompare` VALUES('amar', 'ajay', 'shankar', NULL); 
INSERT INTO `mycompare` VALUES('akbar', 'bhai', 'aslam', 'akbar'); 
INSERT INTO `mycompare` VALUES('anthony', 'john', 'Jim', 'Ken'); 
_____ 

SELECT * FROM mycompare WHERE (name = fname OR name = mname OR name = lname) 
akbar bhai aslam akbar 

select * from mycompare where !(name = fname OR name = mname OR name = lname) 
anthony john Jim Ken 

在上面的第二個選擇中,我期望「amar」記錄也是因爲該名稱與第一個,第二個或最後一個名稱不匹配。與NULL值比較

回答

28

NULL任何比較得出NULL。爲了克服這個問題,有三個運營商可以使用:

  • x IS NULL - 確定左手錶達式是否是NULL
  • x IS NOT NULL - 像上面,但是相反,
  • x <=> y - 這兩個操作數的相等比較以安全的方式,即NULL被視爲正常值。

爲您的代碼,你可能要考慮使用第三個選項,並與空安全比較去:

SELECT * FROM mycompare 
WHERE NOT(name <=> fname OR name <=> mname OR name <=> lname) 
+0

更多信息:[MySQL的比較函數和操作符(HTTP://dev.mysql。 COM/DOC/refman/5.7/EN /比較-operators.html) – IvanRF 2016-08-25 19:28:16

2

NULL如果您進行值比較(因爲NULL不是值),會自動省略值。您的where子句基本上意思是:比較提及的字段的值,,如果它們的值爲-其他爲false。

如果您還想要這些行,則必須包含一個單獨的支票NULL

1

你也許可以逃脫類似如下(假設映射爲NULL「」不是問題):

SELECT * FROM mycompare 
WHERE (ifnull(name,'') = ifnull(fname,'') 
     OR ifnull(name,'') = ifnull(mname,'') 
     OR ifnull(name,'') = ifnull(lname,'')); 

select * from mycompare 
where !(ifnull(name,'') = ifnull(fname,'') 
     OR ifnull(name,'') = ifnull(mname,'') 
     OR ifnull(name,'') = ifnull(lname,'')); 
3

我有同樣的問題,當我在寫UPDATE觸發器,想要執行部分的代碼只有當兩個值不同時。使用IS NULLXOR派上了用場:

SELECT 1!=1;       -- 0 
SELECT 1!=2;       -- 1 
SELECT 1!=NULL;      -- NULL 
SELECT NULL!=NULL;     -- NULL 
SELECT NULL IS NULL XOR 1 IS NULL; -- 1 
SELECT NULL IS NULL XOR NULL IS NULL; -- 0 
SELECT 1 IS NULL XOR 1 IS NULL;  -- 0 

所以我已經結束了使用:

IF (OLD.col != NEW.col) OR ((OLD.col IS NULL) XOR (NEW.col IS NULL)) THEN ...