【问题标题】:Does the order of columns matter in a group by clause?在 group by 子句中,列的顺序是否重要?
【发布时间】:2011-03-05 03:04:21
【问题描述】:

如果我有两列,一列具有非常高的基数,另一列具有非常低的基数(唯一的 # 个值),我分组的顺序是否重要?

这是一个例子:

select 
     dimensionName, 
     dimensionCategory, 
     sum(someFact)
from SomeFact f
join SomeDim d on f.dimensionKey = d.dimensionKey
group by 
    d.dimensionName,  -- large number of unique values
    d.dimensionCategory -- small number of unique values

是否存在重要的情况?

【问题讨论】:

标签: sql sql-server group-by


【解决方案1】:

不,对于 GROUP BY 子句,顺序无关紧要。

MySQL 和 SQLite 是我所知道的唯一允许您选择从 group by 中省略的列的数据库(非标准,不可移植),但顺序也不重要。

【讨论】:

    【解决方案2】:

    SQL 是声明性的。

    在这种情况下,您已经告诉优化器您希望如何对数据进行分组,并且它知道如何进行。

    它不会逐行(程序)评估并先查看一列

    主要的地方列顺序是索引。 col1, col2col2, col1 不同。完全没有。

    【讨论】:

    • ORDER BY 也很重要。
    【解决方案3】:

    Microsoft SQL Server 有一个遗留的非标准功能,称为 ROLLUP。 ROLLUP 是 GROUP BY 语法的扩展,当使用它时,GROUP BY 列的顺序决定了哪些列应该在结果中分组。然而,ROLLUP 已被弃用。标准 SQL 替代方法是使用 SQL Server 2008 及更高版本支持的分组集。

    【讨论】:

      【解决方案4】:

      因为这里没有提到。以上答案都是正确的,即“group by”子句后的列顺序不会影响查询的正确性(即总金额)。

      但是,正在检索的行的顺序将根据“group by”子句后指定的列的顺序而有所不同。例如,考虑具有以下行的表 A

      Col1 Col2 Col3
      1   xyz 100
      2   abc 200
      3   xyz 300
      3   xyz 400
      

      SELECT *, SUM(Col3) FROM A GROUP BY Col2, Col1 将检索按Col2 升序排列的行。

      Col1 Col2 Col3 sum(Col3)
      2   abc 200 200
      1   xyz 100 100
      3   xyz 300 700
      

      现在将 group by 中列的顺序更改为 Col1, Col2。检索到的行按Col1 升序排列。

      select *, sum(Col3) from A group by Col1, Col2

      Col1 Col2 Col3 sum(Col3)
      1   xyz 100 100
      2   abc 200 200
      3   xyz 300 700
      

      注意:求和量(即查询的正确性)保持不变。

      【讨论】:

      • 但是,除非使用“ORDER BY”,否则选择结果的行顺序无论如何都是未定义的,不是吗?所以你不应该依赖任何特定的行顺序,即使根本不使用 GROUP BY。
      • 同意@avl_sweden,我认为响应至少应该表明这种行为是特定于实现的。不能保证更新(甚至相同)版本的 SQL Server 不会产生不同的排序。
      【解决方案5】:

      如果我有两列,一列具有非常高的基数,另一列具有非常低的基数(唯一的 # 个值),我分组的顺序是否重要?

      查询 1

      SELECT spec_id, catid, spec_display_value, COUNT(*) AS cnt  FROM tbl_product_spec 
      GROUP BY spec_id, catid, spec_display_value ;
      

      查询 2

      SELECT spec_id, catid, spec_display_value, COUNT(*) AS cnt  FROM tbl_product_spec FORCE INDEX(idx_comp_spec_cnt)
      GROUP BY catid, spec_id,spec_display_value;
      

      两者相等,顺序在 group by 子句中不起作用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-11-08
        • 1970-01-01
        • 1970-01-01
        • 2012-07-11
        • 1970-01-01
        • 2017-12-19
        • 1970-01-01
        相关资源
        最近更新 更多