SQL 查询消息 table returns 并非所有结果。奇怪的行为
SQL query on messages table returns not all results. Strange behavior
谁能帮忙。我在 SQL 查询“消息”table 时有奇怪的行为。
对于每个联系目标用户的用户,它应该 return MAX(id)。
Table很简单:
id(int, ai) | from(int) | dest(int) | text(txt) | time(int) | msg_status(int)
USERS table 只有 5 个测试用户。
MSG table 有大约 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,我有:
- 最大值(
id
) 37, 30, 33, 36
1 号用户与其他 4 位用户都有对话消息。
但是对于5号用户我有:
- 最大(
id
) 36
因此这是不正确的。由于 5 号用户有最后一条消息,如下所述:
id from dest text
35 5 2 hellp
36 5 1 hi there
所以少了一个结果,因为它必须是这样的:
- 最大值(
id
) 35, 36
但事实并非如此。
有人能指出哪里出了问题吗?
UPD.
简化查询:
SELECT * FROM `msg` WHERE `id` IN (SELECT MAX(`id`) FROM `msg`
WHERE `from` = '5' OR `dest` = '5' GROUP BY `from`, `dest`);
我收到结果:
id from desr text
32 1 5 test
35 5 2 hello
36 5 1 test2
所以原始查询必须产生 35 和 36 结果,因此只给出 36...
对于 Id 35 和 36,2 个 GROUP BY 语句应该 return 相同的值 (5),因此 MAX(id) 将 return 36 - 这就是你得到的。
您的 SQL 与您的结果相符,因此一切似乎都有效。如果结果不是您想要的,那么您需要更改 SQL - 如果您需要帮助,那么您需要解释 return ID 35 和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
and Least
函数:
GROUP BY Greatest(`from`, `dest`), Least(`from`, `dest`)
谁能帮忙。我在 SQL 查询“消息”table 时有奇怪的行为。 对于每个联系目标用户的用户,它应该 return MAX(id)。
Table很简单:
id(int, ai) | from(int) | dest(int) | text(txt) | time(int) | msg_status(int)
USERS table 只有 5 个测试用户。
MSG table 有大约 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,我有:
- 最大值(
id
) 37, 30, 33, 36
1 号用户与其他 4 位用户都有对话消息。
但是对于5号用户我有:
- 最大(
id
) 36
因此这是不正确的。由于 5 号用户有最后一条消息,如下所述:
id from dest text
35 5 2 hellp
36 5 1 hi there
所以少了一个结果,因为它必须是这样的:
- 最大值(
id
) 35, 36
但事实并非如此。
有人能指出哪里出了问题吗?
UPD.
简化查询:
SELECT * FROM `msg` WHERE `id` IN (SELECT MAX(`id`) FROM `msg`
WHERE `from` = '5' OR `dest` = '5' GROUP BY `from`, `dest`);
我收到结果:
id from desr text
32 1 5 test
35 5 2 hello
36 5 1 test2
所以原始查询必须产生 35 和 36 结果,因此只给出 36...
对于 Id 35 和 36,2 个 GROUP BY 语句应该 return 相同的值 (5),因此 MAX(id) 将 return 36 - 这就是你得到的。
您的 SQL 与您的结果相符,因此一切似乎都有效。如果结果不是您想要的,那么您需要更改 SQL - 如果您需要帮助,那么您需要解释 return ID 35 和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
and Least
函数:
GROUP BY Greatest(`from`, `dest`), Least(`from`, `dest`)