代码之家  ›  专栏  ›  技术社区  ›  Arth

任意选择的非聚合列是否保证来自MySQL GROUP BY的同一行?

  •  3
  • Arth  · 技术社区  · 6 年前

    与其说是我想用的东西,不如说是个有趣的问题

      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 划船?

    我知道,至少

    我在文件里找不到任何东西,也找不到可靠的方法来测试这个

    更新

    据我所知这不是一个复制品。。我想知道当从同一个表中选择两个不同的列时,值的任意选择是否来自同一个任意选择的行

    其他问题似乎不太具体,更倾向于任意选择一个或多个非聚合列的行和值

    1 回复  |  直到 6 年前
        1
  •  2
  •   O. Jones    6 年前

    GROUP BY . 阅读此内容了解更多信息 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\u user.id对于每一行都是唯一的,就可以得到正确的名称,因为它依赖于id值。

    但是对于另一个表中的值,你的结果,正式地说, 不可预知的 . 他们是从同一排回来的吗?不可预知的。

    不可预测就像随机的,但更糟。Random意味着您有时会得到不同的值,所以您可以在测试中发现问题。不可预测意味着每次都会得到相同的值, 直到你不这样做。 通常,当表和索引变大时,所选值会发生变化。

    您可能希望使用可提供可预测结果的查询。例如,这个将返回 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
    

    检索最大的 站点\用户\地址.id user_id id 价值观。

    当心 记录在案。文件上说是的 不确定。

    这种不可预测性很难让程序员绞尽脑汁。我们不能容忍程序性Java或php代码中的不可预测性。但是SQL是声明性的,几千年来程序员一直致力于使查询快速运行。不要试图胜过DBMS,即使你是 Michael Stonebraker