除了我要使用的东西以外,还有更多有趣的问题
说我运行以下查询:
SELECT su.id, su.name, sua.line_1, sua.line_2
FROM site_user su
JOIN site_user_address sua
ON sua.user_id = su.id
WHERE su.id = 1
GROUP BY su.id /* id is the PK for site_user */
是否保证sua.line_1
和sua.line_2
从同一行site_user_address
返回?
我知道,至少site_user_address
行是任意选择的
我在文档中找不到任何内容,也无法想到一种可靠的测试方法
更新
据我所知,这不是重复项。.我想知道,当从同一张表中选择两个不同的列时,是否会任意选择来自同一行的值?
其他问题似乎不太具体,而是直接针对一个或多个非聚合列的行和值的任意选择
答案 0 :(得分:2)
您确实在利用臭名昭著的GROUP BY
的MySQL非标准实现。请阅读以获取更多信息https://dev.mysql.com/doc/refman/8.0/en/group-by-handling.html
您的查询等效于using ANY_VALUE()
来获取第二张表中的值,就像这样。
SELECT su.id, su.name,
ANY_VALUE(sua.line_1) line_1,
ANY_VALUE(sua.line_2) line_2
FROM site_user su
JOIN site_user_address sua
ON sua.user_id = su.id
WHERE su.id = 1
GROUP BY su.id
只要site_user.id对于每一行都是唯一的,您将获得正确的名称,因为它取决于id值。
但是对于另一个表中的值,从形式上来说,您的结果将是不确定的或不可预测的。他们是否从同一行回来?变幻莫测。
不可预测的就像随机的,但更糟。随机表示有时会获得不同的值,因此您可以在测试中发现问题。不可预测的意思是每次您都会获得相同的值,直到您没有。通常,当表和索引变大时,所选值会发生变化。
您可能希望使用可提供可预测结果的查询。例如,此行将返回site_user_address
的最高值的site_user_address.id
行。
SELECT su.id, su.name,
sua.line_1, sua.line_2
FROM site_user su
JOIN (
SELECT MAX(id) id, user_id
FROM site_user_address
GROUP BY user_id
) sumax ON su.id = sumax.user_id
JOIN site_user_address sua ON sumax.id = sua.id
WHERE su.id = 1
子查询:
SELECT MAX(id) id, user_id
FROM site_user_address
GROUP BY user_id
为每个site_user_address.id
值检索最大的user_id
值。然后,您可以连接到site_user_address表以提取那些id
值的详细值。
当心的诱惑力是为了推断行为是在DBMS中设计的,但没有记录,只是因为您观察到了它们。问题 中的行为已记录在案。该文档说这是不确定的。这意味着DBMS查询计划器可以自由地以最有效的方式满足您的查询。随着表和索引的增长,查询计划者可以而且确实会选择不同的方式来满足相同的查询。不同的查询计划也可能来自驻留在缓存中的表的不同部分。等等
对于程序员来说,这种不可预测性很难使我们动脑筋。我们不会容忍程序Java或php代码中的不可预测性。但是SQL是声明性的,并且数千名程序员已经进入使查询快速运行的阶段。即使您自己Michael Stonebraker,也不要试图超越DBMS。