2010-03-06 144 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 ...