0

我有一个消息表,其中包含我运行一些运算符的列。有几个 threadid,我通过检查一个值是否匹配 uidto 或 uidfrom 来提取消息,然后检查一个值是否在 hidden1 或 hidden2 中(或者基本上一个用户删除了线程,但我们希望它仍然对另一个用户可见...)

编辑:
值得注意的是, hidden1 和 hidden2 列的值是选择对自己隐藏线程的用户 ID。

当一个用户有多个线程,并且我将一个线程设置为已删除(hidden1 值 = 1)时,查询不会拉取任何其他线程,尽管它们的 hidden1 和 hidden2 列仍然为 NULL。

我在这里有一个 SQL Fiddle,其中包含表中的数据和我一直在玩的查询:http ://sqlfiddle.com/#!2/e3c39c/3

显示具有多个 threadid 的所有结果
注意只有 threadid 1 的列 hidden1 具有值

SELECT uidto, uidfrom, threadid, hidden1, hidden2 FROM messages;

尝试提取结果
mysql 看到我的线程之一,其列 hidden1 具有值并且没有显示,即使其他线程 hidden1 和 hidden2 列仍然为 NULL?

SELECT * FROM messages
WHERE (uidto=1 OR uidfrom=1)
AND (hidden1 <> 1 OR hidden2 <> 1)
GROUP BY threadid
ORDER BY last_activity DESC
4

1 回答 1

0

任何与 NULL 的算术比较总是返回 NULL并被视为 false;在这种情况下,这意味着hidden1 <> 1,当 hidden1 为 NULL 时,返回一个有效的假值,尽管 NULL 显然不等于 1,或者实际上不等于包括它自己在内的任何其他值。(试试看!SELECT NULL = NULL你会返回 NULL。)

要解决此问题,请将不等式比较替换为IS NULL,或者(最好)使用整数零而不是 NULL 来表示您的错误值,以便您可以使用算术比较进行真值测试。

在不更改数据的情况下,您可以通过将比较替换为可识别 NULL 的比较来使查询正常工作,因此:

SELECT * FROM messages
WHERE (uidto=1 OR uidfrom=1)
    AND (hidden1 IS NULL OR hidden2 IS NULL)
GROUP BY threadid
ORDER BY last_activity DESC

结果是

ID  UIDTO   UIDFROM     THREADID    MESSAGE     STATUS  DATETIME                            LAST_ACTIVITY                       LAST_MESSAGE            HIDDEN2     HIDDEN1     TYPE
1   10002   1           1           hey         0       November, 14 2013   00:28:58+0000   November, 14 2013 00:36:13+0000     hans here.              (null)      1           message
3   15047   1           3           CJ TO BG    0       November, 14 2013   00:34:53+0000   November, 14 2013 00:34:53+0000     CJ TO BG                (null)      (null)      message

(另请参阅更新的小提琴。)

于 2013-11-14T02:17:15.927 回答