[英]column <> 1 returns False on NULL values
我有两张桌子。 offers
和offer_status
。 我想从返回行offers
在offer_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”的实际行为之间的区别。
引用MySQL文档 :
如果一个或两个参数均为NULL,则比较的结果为NULL,但NULL安全的<=>相等比较运算符除外。 对于NULL <=> NULL,结果为true。
所以我认为是的(disabled IS NULL OR disabled=0)
是必要的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.