sql - 带和不带 ORDER BY 子句的分区分析计数

标签 sql oracle window-functions

我不明白为什么在使用 ORDER BY 时会有不同的结果分析中的子句 COUNT功能。

使用一个简单的例子:

with req as
 (select 1 as n, 'A' as cls
    from dual
  union
  select 2 as n, 'A' as cls
    from dual)
select req.*, count(*) over(partition by cls) as cnt from req;

给出以下结果:
N   CLS CNT
2   A   2
1   A   2

而当添加 ORDER BY 时在分析从句中,结果是不同的!
with req as
 (select 1 as n, 'A' as cls
    from dual
  union
  select 2 as n, 'A' as cls
    from dual)
select req.*, count(*) over(partition by cls order by n) as cnt from req;

CNT 列更改:
N   CLS CNT
1   A   1
2   A   2

有人可以解释一下吗?

谢谢

最佳答案

首先,一个link到文档。然而,它有些晦涩。

分析子句由 query_partition_clause 组成, order_by_clausewindowing_clause .而且,关于 windowing_clause 的一件非常重要的事情是

You cannot specify this clause unless you have specified the order_by_clause. Some window boundaries defined by the RANGE clause let you specify only one expression in the order_by_clause. Refer to "Restrictions on the ORDER BY Clause".



但不仅不能用windowing_clause没有 order_by_clause ,它们被捆绑在一起。

If you omit the windowing_clause entirely, then the default is RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW.



默认窗口子句产生类似于运行总计的东西。 COUNT返回 1对于第一行,因为窗口顶部和当前行之间只有一行,2对于第二行,依此类推。

因此,在您的第一个查询中根本没有窗口,但在第二个查询中有默认窗口。

您可以通过指定完全无界窗口来模拟第一个查询的行为。
with req as
 (select 1 as n, 'A' as cls
    from dual
  union
  select 2 as n, 'A' as cls
    from dual)
select req.*, count(*) over(partition by cls order by n RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as cnt from req;

是的
N   CLS CNT
1   A   2
2   A   2

关于sql - 带和不带 ORDER BY 子句的分区分析计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41364665/

相关文章:

sql - Google数据存储区Nosql和Google bigquery sql之间的实际区别是什么?

sql - Oracle SQL 按级别连接

sql - Oracle 最小值和最大值(相同值)

sql - 查询以查找间隔超过特定间隔的所有时间戳

mysql - 我的 TRIGGER sql 语句有什么问题 - MySQL

mysql - 使用将表连接到自身并连接另一个表

php - 按 mysql 选项分组

c++ - Oracle OCI 将无效的 UTF8 字符更改为 U+FFFD

sql - 使用滞后窗口函数找到正确的分区

sql - 基于行的顺序分组