加窗函数在 ANSI 规范中定义为在处理 , , 之后GROUP BY
逻辑HAVING
执行WHERE
。
更具体地说,它们在此处的逻辑查询处理流程图的步骤 5.1 和 6 中被允许。
我想他们可以用另一种方式定义它并允许使用窗口函数GROUP BY
,窗口WHERE
是HAVING
该阶段开始时的逻辑结果集,但假设他们有并且我们被允许构造查询,例如
SELECT a,
b,
NTILE(2) OVER (PARTITION BY a ORDER BY b) AS NtileForSelect
FROM YourTable
WHERE NTILE(2) OVER (PARTITION BY a ORDER BY b) > 1
GROUP BY a,
b,
NTILE(2) OVER (PARTITION BY a ORDER BY b)
HAVING NTILE(2) OVER (PARTITION BY a ORDER BY b) = 1
有四个不同的逻辑窗口在运行,祝你好运,弄清楚这会是什么结果!另外,如果HAVING
您实际上想通过GROUP BY
上面级别的表达式进行过滤,而不是将行窗口作为 ? 之后的结果,该GROUP BY
怎么办?
CTE 版本更详细,但也更明确且更易于理解。
WITH T1 AS
(
SELECT a,
b,
NTILE(2) OVER (PARTITION BY a ORDER BY b) AS NtileForWhere
FROM YourTable
), T2 AS
(
SELECT a,
b,
NTILE(2) OVER (PARTITION BY a ORDER BY b) AS NtileForGroupBy
FROM T1
WHERE NtileForWhere > 1
), T3 AS
(
SELECT a,
b,
NtileForGroupBy,
NTILE(2) OVER (PARTITION BY a ORDER BY b) AS NtileForHaving
FROM T2
GROUP BY a,b, NtileForGroupBy
)
SELECT a,
b,
NTILE(2) OVER (PARTITION BY a ORDER BY b) AS NtileForSelect
FROM T3
WHERE NtileForHaving = 1
由于这些都在SELECT
语句中定义并且具有别名,因此很容易消除来自不同级别的结果的歧义,例如只需切换WHERE NtileForHaving = 1
到NtileForGroupBy = 1