对消息表的SQL查询不返回所有结果.奇怪的行为



有人能帮帮我吗?我对"消息"的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有效。

为了避免这个错误,最好使用GreatestLeast函数:

GROUP BY Greatest(`from`, `dest`), Least(`from`, `dest`)

对于Id 35和36,2个GROUP BY语句应该返回相同的值(5),因此MAX(Id)将返回36 -这就是您所得到的。

你的SQL匹配你的结果,所以这一切似乎都在工作。如果结果不是你想要的,那么你需要改变你的SQL -如果你需要帮助,那么你需要解释的逻辑是什么,将返回id 35和36

最新更新