Mysql 如果条件与NULL无关,则消除具有NULL值的行

Mysql 如果条件与NULL无关,则消除具有NULL值的行,mysql,join,Mysql,Join,如果我没有将置于WHERE条件下,我会看到关系列的NULL行,即beta没有阻止delta 但是当我取消注释WHERE条件时,我希望只剩下这一行。但它也被淘汰了。为什么会发生这种情况,以及如何正确编写查询?谢谢。在SQL中,与某些编程语言不同,在某些编程语言中,您可以使用相等的(=)elvaluator来测试NULL,而在ANSI SQL中,您不能且必须为NULL或相反的不为NULL来计算空值。这意味着如果您使用=求值,并且一行有NULL值,它甚至不会被考虑,至少对于MySQL InnoDB,一

如果我没有将
置于WHERE
条件下,我会看到关系列的
NULL
行,即beta没有阻止delta


但是当我取消注释
WHERE
条件时,我希望只剩下这一行。但它也被淘汰了。为什么会发生这种情况,以及如何正确编写查询?谢谢。

在SQL中,与某些编程语言不同,在某些编程语言中,您可以使用相等的(
=
)elvaluator来测试
NULL
,而在
ANSI SQL
中,您不能且必须
为NULL
或相反的
不为NULL
来计算空值。这意味着如果您使用
=
求值,并且一行有
NULL
值,它甚至不会被考虑,至少对于
MySQL InnoDB
,一些
RMBD
处理它们的方式略有不同

现在,对于您的具体情况,您可以像这样修改查询以获得所需的结果

CREATE TABLE players (
  `userID` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(45) NOT NULL,
PRIMARY KEY (`userID`));

CREATE TABLE opponents (
  `userID` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(45) NOT NULL,
PRIMARY KEY (`userID`));

CREATE TABLE relationship (
  `user1_userID` INT NOT NULL,
  `user2_userID` INT NOT NULL,
  `blocked` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`user1_userID`, `user2_userID`));

INSERT INTO players (`name`) 
VALUES ('alpha'), ('beta'), ('gamma'), ('delta');

INSERT INTO opponents (`name`) 
VALUES ('alpha'), ('beta');

INSERT INTO relationship (`user1_userID`, `user2_userID`, `blocked`)
VALUES (1,2, 1), (1,3, 1), (1,4, 1), (2, 1, 1), (2,3, 1), (3,4, 1);

SELECT o.userID, o.name, ur.*
FROM opponents o
LEFT JOIN players p
    ON (o.userID != p.userID)
LEFT JOIN relationship ur
    ON ((ur.user1_userID = p.userID AND ur.user2_userID = o.userID) OR 
       (ur.user1_userID = o.userID AND ur.user2_userID = p.userID)) 
-- WHERE (ur.blocked != 1)
已更新

因为我猜有时候我不是最好的解释者,最后我只是互联网上的一个家伙,这里有一些mysql文档的链接,应该可以帮助你把事情弄清楚一点。希望这有助于回答“真正的问题”

编辑

我想为了更好地解释我自己,值
NULL
不能由布尔运算符计算,因为
NULL
是没有值的,因为它没有值,所以既不能是1也不能是0。因此,在任何布尔运算中,它都不会返回false,例如
NULL=1
NULL=1
均为假。现在我还想提到一些可能的替代解决方案,因为在数据库中,如果您想从数据库中获得准确的信息,正确地处理空值是非常重要的

MySQL
中,除了
之外,还可以使用两个函数=将为您提供所需的结果

SELECT o.userID, o.name, ur.*
FROM opponents o
LEFT JOIN players p
    ON (o.userID != p.userID)
LEFT JOIN relationship ur
    ON ((ur.user1_userID = p.userID AND ur.user2_userID = o.userID) OR 
       (ur.user1_userID = o.userID AND ur.user2_userID = p.userID)) 
WHERE (ur.blocked != 1 OR ur.blocked IS NULL)
COALESCE(value,…)
可以指定许多值,并将返回从左到右的第一个非空值。因此,在您的情况下,它将
NULL
计算为
0
,这将不等于
1
,并将返回丢失的记录

COALESCE(ur.blocked,0) != 1
IFNULL(Value1,Value2)
如果第一个值不是
NULL
,此函数将返回第一个值;如果第一个值是
NULL


希望这将有助于您将来处理
NULL
值。

将where子句更改为where ur.blocked IS NULLUsing(ur.blocked IS NULL)将是临时解决方法。假设结果中有另一行,其(ur.blocked为0)。我们希望所有行都具有NULL或0(基本上!=1)。真正的问题是,(ur.blocked!=1)为什么要删除ur.blocked为NULL的行?它为NULL的原因是因为联接中没有匹配的行。使用ur.blocked为NULL或ur.blocked 1的位置。真正的问题是,(ur.blocked!=1)为什么要删除ur.blocked为NULL的行?您的回答谈到了(ur.blocked=NULL)在mysql中不起作用的原因我想尝试总结一下我在mysql InnoDB中试图说的内容,其中有一个字段具有NULL值,该字段将根据where子句中的
=
求值器进行限制,它将删除该字段为空的所有记录,因为
=
或在本例中
无法对其求值=
IFNULL(ur.blocked,0) != 1