繁体   English   中英

列<> 1对NULL值返回False

[英]column <> 1 returns False on NULL values

我有两张桌子。 offersoffer_status 我想从返回行offersoffer_status行是丢失或disabled该表列是0。

这是我尝试执行的操作:

SELECT offers.id,network,campid,name,url FROM offers
LEFT JOIN offer_status ON offers.id = offer_status.sql_id
AND offer_status.user_id='3'
WHERE country='US'

AND offer_status.disabled != '1'

ORDER BY epc DESC LIMIT 7

但是,如果offer_status中的行不存在(并且JOIN失败),则此方法不起作用。 在我看来,由于offer_status.disabled为null,因此它似乎仍然可以工作。

这样做的工作:

SELECT offers.id,network,campid,name,url FROM offers
LEFT JOIN offer_status ON offers.id = offer_status.sql_id
AND offer_status.user_id='3'
WHERE country='US'

AND (offer_status.disabled IS NULL OR offer_status.disabled=0)

ORDER BY epc DESC LIMIT 7

但是对我来说,这似乎在性能方面更差,并且我仍然对我最初的想法没有用感到失望。

上面的OR语句是执行此操作的唯一方法吗? 有没有更好的方法?

SQL逻辑是具有状态TRUE,FALSE和UNKNOWN的三态逻辑。 WHERE子句选择条件评估为TRUE的行。

如果将NULL值与任何非null值进行比较,则会得到第三个逻辑状态UNKNOWN(如标题中所述,不是FALSE)。 这与TRUE不同,因此不会选择条件评估为UNKNOWN的行。

您可以使用显式的IS NULL测试来检查是否为空。

AND (offer_status.disabled != '1' OR offer_status.disabled IS NULL)

请注意额外的括号,以确保安全性,清晰度和准确性。

如果这过多地影响了性能,请对offer_status.disabled列强制执行NOT NULL约束,然后您就不必摆弄IS NULL测试或OR'd条件。 通常,每个可能为NOT NULL的列都应为NOT NULL。 它使您的数据库更容易使用。


请注意,如果offer_status.disabled为NULL,则:

WHERE offer_status.disabled  = '1' -- evaluates to UNKNOWN and the row is not selected
WHERE offer_status.disabled != '1' -- evaluates to UNKNOWN and the row is not selected

这是标题中所声称的不正确的“与NULL的比较返回FALSE”与“与NULL的比较返回UNKNOWN”的实际行为之间的区别。

NULL (使用=<><>等)与另一个值进行比较会产生NULL 而且NULL既不是true,也不是false。 其次,为了满足WHERE子句,条件必须评估为true。

因此,您的第二个查询实际上是正确的方法。

为了完整起见,可以(但不建议)使用诸如IFIFNULL函数重写查询,例如:

WHERE IFNULL(offer_status.disabled, 0) = 0

引用MySQL文档

如果一个或两个参数均为NULL,则比较的结果为NULL,但NULL安全的<=>相等比较运算符除外。 对于NULL <=> NULL,结果为true。

所以我认为是的(disabled IS NULL OR disabled=0)是必要的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM