有人能帮帮我吗?我对"消息"的SQL查询有奇怪的行为。表格它应该为每个联系的目标用户返回MAX(id)。
表很简单:
id(int, ai) | from(int) | dest(int) | text(txt) | time(int) | msg_status(int)
表中只有5个测试用户
味精表有大约40条消息。
当我查询大多数用户id(1,2,3,4) -我收到正常的结果
当我查询一个特定的用户No.5-我收到one更少的结果。
查询为:
SELECT MAX(`id`) FROM `msg` WHERE `from` = '5' OR `dest` = '5'
GROUP BY (IF(`from` > `dest`, `from`, `dest`)), (IF(`from` < `dest`, `dest`, `from`));
对于大多数用户,它给出正常的结果。例如,对于用户1,我有:
- MAX(
id
) 37,30,33,36
当用户1与其他4个用户有对话消息时,这是OK的。
但是对于用户5,我有:
- MAX(
id
) 36
因此这是不正确的。用户5有如下所述的最后消息:
id from dest text
35 5 2 hellp
36 5 1 hi there
所以少了一个结果,因为它必须是这样的:
- MAX(
id
) 35,36
但事实并非如此。
谁能告诉我出了什么问题?
乌利希期刊指南。
简化查询:
SELECT * FROM `msg` WHERE `id` IN (SELECT MAX(`id`) FROM `msg`
WHERE `from` = '5' OR `dest` = '5' GROUP BY `from`, `dest`);
I receive result:
id from desr text
32 1 5 test
35 5 2 hello
36 5 1 test2
所以原始查询必须产生35和36的结果,因此只给出36…
在GROUP BY
表达式中有一个逻辑错误:
GROUP BY
(IF(`from` > `dest`, `from`, `dest`)),
(IF(`from` < `dest`, `dest`, `from`));
如果from > dest
,则此等价于GROUP BY from, from
;如果是from < dest
,那么这就是GROUP BY dest, dest
。对于具有from = 5
的两个示例行,它们按from
分组,因此在同一组中,因此MAX(id)
为36,结果中没有35。
相反,与任何其他用户ID相比,ID 1将是最小的,因此在查询ID 1时,查询将按其他ID分组,确保它们保持单独的组。这就是为什么查询对ID 1有效。
为了避免这个错误,最好使用Greatest
和Least
函数:
GROUP BY Greatest(`from`, `dest`), Least(`from`, `dest`)
对于Id 35和36,2个GROUP BY语句应该返回相同的值(5),因此MAX(Id)将返回36 -这就是您所得到的。
你的SQL匹配你的结果,所以这一切似乎都在工作。如果结果不是你想要的,那么你需要改变你的SQL -如果你需要帮助,那么你需要解释的逻辑是什么,将返回id 35和36