列<> 1对NULL值返回False

时间:2012-12-26 07:11:24

标签: php mysql sql

我有两张桌子。 offersoffer_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语句是唯一的方法吗?有更好的方法吗?

3 个答案:

答案 0 :(得分:2)

SQL逻辑是一种三态逻辑,状态为TRUE,FALSE和UNKNOWN。 WHERE子句选择条件求值为TRUE的行。

如果将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条件。通常,每个可能都是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'的实际行为。

答案 1 :(得分:1)

NULL(使用=<><>等)与其他值进行比较,得出NULL。而NULL既不是真的,也不是假的。其次,为了满足WHERE子句,条件必须评估为真。

所以,你的第二个查询实际上是正确的方法。

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

WHERE IFNULL(offer_status.disabled, 0) = 0

答案 2 :(得分:0)

引自MySQL document

  

如果一个或两个参数为NULL,则比较结果为   NULL,除了NULL-safe&lt; =&gt;平等比较运算符。对于   NULL&lt; =&gt; NULL,结果为true。

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