【问题标题】:why adding order by in the query changes the aggregate value?为什么在查询中添加 order by 会更改聚合值?
【发布时间】:2021-12-22 13:34:26
【问题描述】:

以下vertica 示例来自https://www.vertica.com/docs/11.0.x/HTML/Content/Authoring/AnalyzingData/SQLAnalytics/AnalyticFunctionsVersusAggregateFunctions.htm?tocpath=Analyzing%20Data%7CSQL%20Analytics%7C_____2

CREATE TABLE employees(emp_no INT, dept_no INT);
INSERT INTO employees VALUES(1, 10);
INSERT INTO employees VALUES(2, 30);
INSERT INTO employees VALUES(3, 30);
INSERT INTO employees VALUES(4, 10);
INSERT INTO employees VALUES(5, 30);
INSERT INTO employees VALUES(6, 20);
INSERT INTO employees VALUES(7, 20);
INSERT INTO employees VALUES(8, 20);
INSERT INTO employees VALUES(9, 20);
INSERT INTO employees VALUES(10, 20);
INSERT INTO employees VALUES(11, 20);
COMMIT;

如果我在没有 order by 的情况下运行此查询,我会得到所有行的相同计数值

dbadmin@b006bc38a718(*)=> 
select 
  emp_no
, dept_not
, count(*) over (partition by dept_not) as emp_count 
from employees;
 emp_no | dept_not | emp_count
--------+----------+-----------
      6 |       20 |         6
      7 |       20 |         6
      8 |       20 |         6
      9 |       20 |         6
     10 |       20 |         6
     11 |       20 |         6
      1 |       10 |         2
      4 |       10 |         2
      2 |       30 |         3
      3 |       30 |         3
      5 |       30 |         3
(11 rows)

但如果我添加order by,我会获得增量价值

dbadmin@b006bc38a718(*)=> 
select 
  emp_no
, dept_not
, count(*) over (partition by dept_not order by emp_no) as emp_count 
from employees;
 emp_no | dept_not | emp_count
--------+----------+-----------
      2 |       30 |         1
      3 |       30 |         2
      5 |       30 |         3
      1 |       10 |         1
      4 |       10 |         2
      6 |       20 |         1
      7 |       20 |         2
      8 |       20 |         3
      9 |       20 |         4
     10 |       20 |         5
     11 |       20 |         6
(11 rows)

Time: First fetch (11 rows): 85.075 ms. All rows formatted: 85.139 ms

order by 的作用是什么?为什么我会获得增量价值?

【问题讨论】:

    标签: vertica


    【解决方案1】:

    如果window子句只包含PARTITION BY,则返回分区的总和——对于分区的每一行相同的值。

    如果窗口子句同时包含PARTITION BY 和ORDER BY,则返回分区内的运行计数。因此,使用ORDER BY 表达式,到目前为止已在分区内计算了多少行。

    这正是窗口函数的工作原理。它们为您提供了无限可能...

    【讨论】:

    • 好的。虽然提供一种获取运行计数的方法可能很有价值,但我觉得使用短语order by 并不是最好的选择,而且会引起混淆。似乎运行计数是order by 的副作用
    • 和partition by 似乎与group by 相同。想知道为什么不使用短语 group by 而不是 partition by,因为 partition 在 Vertica 中有另一个含义。
    • 是的,Manu - 但是如果您选择SUM(amount) OVER(PARTITION BY iso_ctry ORDER BY sales_dt),您将获得一段时间内每个国家/地区的销售总和。这实际上很方便......
    • GROUP BY 每个GROUP BY 列列表组合返回一行,减少行数。 PARTITION BY 返回所有输入行,但可以为分区中的所有行返回相同的结果。这是两个非常不同的用例。
    • 如果我需要每个输入行的输出值,我是否正确使用分析函数而不是聚合函数?
    【解决方案2】:

    发生这种情况是因为 Vertica 应用了默认的 frame-clause,其定义为:

    RANGE UNBOUNDED PRECEDING AND CURRENT ROW
    

    因此,为了获得您想要的结果,您可能需要在 ORDER BY 之后的 OVER() 子句中添加以下框架子句:

    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
    

    此行为记录为:

    如果 OVER 子句省略了指定窗口框架,该函数会创建一个默认窗口,该窗口从当前行扩展到当前分区中的第一行。

    Link to doc

    【讨论】:

      猜你喜欢
      • 2019-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-02
      相关资源
      最近更新 更多