0

这类似于 MYSQL,并且无法理解为什么我无法在窗口函数中同时使用 SUM 和 POWER。特别是 SUM(POWER("DELTA"... 行抛出以下错误:

SQL compilation error: Window function [AVG(CAST(VALUE AS NUMBER(38,3))) OVER (PARTITION BY ID)] may not be nested inside another window function.

删除此行或将其移至第二个 select 语句可修复错误,并且所有其他 . 我认为这是我对 SQL 的一个更基本的误解。任何想法将不胜感激!

WITH UTILS AS (
SELECT
  ID,
  VALUE AS "TEMP_CELSIUS,
  AVG(VALUE) OVER(PARTITION BY ID) AS "TEMP_AVG",
  VAR_POP(VALUE) OVER(PARTITION BY ID) As "TEMP_VAR",
  STDDEV_POP(VALUE) OVER(PARTITION BY ID) As "TEMP_STD",
  COUNT(VALUE) OVER(PARTITION BY ID) As "DEVICE_N",
  (VALUE-"TEMP_AVG") AS "DELTA",
  SUM(POWER("DELTA", 3)) OVER(PARTITION BY ID) AS "SKEW2"
FROM
  TABLE1
)
SELECT 
  "SKEW2"
FROM
  UTILS
4

1 回答 1

0

为了清楚起见,您的问题并不POWER完全是,而是POWERTEMP_AVG涉及window function.

在标准 SQL 中,我们也不能在同一select list.

这是个问题:

SELECT a + b AS c
     , c + d AS e
  FROM t1
;

以下是标准 SQL 规范的一些片段,它们专门涉及窗口函数和一些支持项。

您询问了“基本 SQL”。虽然您的数据库可能支持非标准行为,但了解标准 SQL 提供的行为可能会有所帮助,至少从基础的角度来看,作为起点。

这只是规范的稍旧版本(基础文档日期为 2011-12)的一小部分细节。这大部分没有改变。

在部分:7.12 <query specification>我们有:

<query specification> ::= SELECT [ <set quantifier> ] <select list> <table expression>

您可以看到 yourselect list后面跟着一个table expression.

您的问题基本上是关于<select list>.

但要理解这种select list行为,我们需要看一下名为 的术语<table expression>

<table expression> ::=
   <from clause>
     [ <where clause> ]
     [ <group by clause> ]
     [ <having clause> ]
     [ <window clause> ]

在对应Syntax Rules的 for a<query expression>中,我们发现以下内容:

2) Let T be the result of the <table expression> simply contained in QSPEC.

基本上,T是您的FROM子句的结果,该子句可选地包括WHERE,GROUP BY等。

现在让我们跳到您询问的表达式,window function.

Syntax Rule适用的:

11) Each column reference contained in a <window function> shall unambiguously reference a column of T.

在您的情况下,您指的derived column是当前的 a select list,而不是 的列T

那就是问题所在。该标准将您限制为仅T.

请注意,我从庞大的规范中挑选出非常小的部分。但我认为这指出了基本的细节。

一种常见的方法是简单地将 移动window function到后续查询表达式,以便它引用T包含第一个派生列的 a。

WITH cte1 AS (
       SELECT ...
            , AVG(...) OVER ... AS temp_avg
         FROM t1
     )
SELECT ...
     , SUM(temp_avg) OVER ...
  FROM cte1
;

在某些情况下,如果您愿意,可以只重复派生列中使用的表达式,而不使用单独的 CTE 术语或派生表。至少在标准 SQL 中,我们不能用两个窗口函数来做到这一点。

于 2021-08-30T23:07:57.703 回答