首页 > 解决方案 > 分区依据与排序依据?

问题描述

我正在尝试这个练习:

Employee_id 是该表的主键。此表的每一行都包含每个员工及其各自团队的 ID。
编写一个 SQL 查询来查找每个员工的团队规模。以任意顺序返回结果表。

列名 类型
员工ID 整数
team_id 整数

我制作了这个解决方案:

SELECT DISTINCT 
employee_id
,COUNT(employee_id) OVER (PARTITION BY team_id ORDER BY employee_id) AS team_size

FROM employee

GROUP BY 
employee_id
,team_id

但这产生了一个奇怪的结果: {"headers": ["EMPLOYEE_ID", "TEAM_SIZE"], "values": [[4, 1], [5, 1], [6, 2], [1, 1] , [2, 2], [3, 3]]}... 然后我删除了ORDER BY employee_id,然后输出如预期的那样。

现在,我了解了 PARTITION BY 的工作原理,它计算了每个团队的员工人数,但我认为 ORDER BY 只在团队内部进行排序。那么,如果团队中的所有员工都被计算在内,而不管订单如何,订单怎么会改变输出呢?

标签: sqloracleoracle11gwindow-functions

解决方案


首先,您想要的查询不使用聚合。这是:

SELECT employee_id,
       COUNT(employee_id) OVER (PARTITION BY team_id) AS team_size
FROM employee;

其次,ORDER BY在窗口函数中使用还添加了一个隐式窗口框架子句。所以你的逻辑是:

COUNT(employee_id) OVER (PARTITION BY team_id
                         ORDER BY employee_id
                         RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
                        )

这适用于所有窗口函数,不仅仅是COUNT(*). 因此,COUNT()仅将员工 id 计数到“当前”员工 id。

在这种情况下,它相当于ROW_NUMBER()因为employee_id是唯一的。一般来说,它等价于DENSE_RANK()


推荐阅读