Oracle Analytic函数 - 如何重用PARTITION BY子句?

时间:2011-03-29 13:12:00

标签: oracle analytic-functions

我已经用Oracle编写了一个复杂的SQL查询,我想在同一个分区上使用两个解析函数。

让我们很简单,但不要太多:

SELECT col1,
       MAX(col2) OVER(PARTITION BY col3, col4, col5, col6,
                                   CASE WHEN col7 LIKE 'foo'
                                        THEN SUBSTR(col7,1,5)
                                        ELSE col7
                                   END
                                   ORDER BY col5 ASC, col6 DESC),
       MIN(col2) OVER(PARTITION BY col3, col4, col5, col6,
                                   CASE WHEN col7 LIKE 'foo'
                                        THEN SUBSTR(col7,1,5)
                                        ELSE col7
                                   END
                                   ORDER BY col5 ASC, col6 DESC)
  FROM my_table;

是否有更优雅的语法来分析PARTITION BY子句?

谢谢。

3 个答案:

答案 0 :(得分:12)

如果你指的是标准的WINDOW子句:

SELECT col1,
       MAX(col2) OVER(w),
       MIN(col2) OVER(w)
FROM my_table
WINDOW w AS (PARTITION BY col3, col4, col5, col6,
                               CASE WHEN col7 LIKE 'foo'
                                    THEN SUBSTR(col7,1,5)
                                    ELSE col7
                               END
                               ORDER BY col5 ASC, col6 DESC);

然后我相信答案是没有,Oracle不支持这个(用11gR2检查)。

答案 1 :(得分:5)

您可以使用子查询因子分析,也称为with子句:

(未测试的)

with t as
( select col1
       , col2
       , col3
       , col4
       , col5
       , col6
       , case col7
         when 'foo' then
           substr(col7,1,5)
         else
           col7
         end col7
    from my_table
)
select col1
     , max(col2) over (partition by col3,col4,col5,col6,col7 order by col5,col6 desc) 
     , min(col2) over (partition by col3,col4,col5,col6,col7 order by col5,col6 desc) 
  from t

的问候,
罗布。

答案 2 :(得分:0)

可以使用SELECT col1, MAX(col2) OVER w AS max_col2, MIN(col2) OVER w AS min_col2 FROM my_table WINDOW w AS (PARTITION BY col3, col4, col5, col6, CASE WHEN col7 LIKE 'foo' THEN SUBSTR(col7,1,5) ELSE col7 END ORDER BY col5 ASC, col6 DESC); 子句重用分区定义。从20c版本开始,Oracle支持它:

EndResult

SELECT语句的query_block子句现在支持window_clause,该子句实现了SQL:2011标准中定义的SQL标准表表达式的window子句。

Enhanced Analytic Functions

SELECT

  • 请注意, OVER window_name 不等同于 OVER(window_name…) OVER(window_name…)表示复制和修改窗口规范,如果引用的窗口规范包含windowing_clause,则将被拒绝。

  • 您不能将现有的窗口名与windowing_clause一起使用


查询可以重写为:

PARTITION BY

请注意,可以扩展窗口定义的一部分,例如查询可以共享SELECT col_x, FIRST_VALUE(col_y) OVER (w ORDER BY col3), FIRST_VALUE(col_z) OVER (w ORDER BY col4) FROM tab WINDOW w AS (PARTITION BY col1, col2); 但排序不同:

PARTITION BY

我们不能执行像共享相同的ORDER BYSELECT col_x, AVG(col_y) OVER (w ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) AS moving_avg_3, AVG(col_y) OVER (w ROWS BETWEEN 5 PRECEDING AND CURRENT ROW) AS moving_avg_5 FROM tab WINDOW w AS (PARTITION BY col1, col2 ORDER BY col3) 但窗口大小不同的事情:

{{1}}