2011-03-29 14 views
8

He escrito una consulta SQL compleja con Oracle en la que quiero usar dos funciones analíticas en la misma partición.Funciones de Oracle Analytic: cómo volver a utilizar una cláusula PARTITION BY?

Vamos a ser bastante simple, pero no demasiado:

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; 

¿Existe una sintaxis más elegante para factorizar la cláusula PARTITION BY?

Gracias.

+0

Considerando que las funciones que está utilizando son 'MAX' y' MIN' y también 'col5' y' col6' están en la 'partition' y' order by', aparece la cláusula 'order by' para cada columna ser redundante –

+0

Tiene razón, pero este fue un simple ejemplo, podría ser LAST_VALUE o cualquier otra analítica. – Benoit

+0

posible duplicado de [Aplicar varias funciones de ventana en la misma partición] (http://stackoverflow.com/questions/1896102/applying-multiple-window-functions-on-same-partition). Este duplicado no fue fácil de encontrar. – Benoit

Respuesta

12

Si se refiere a la cláusula estándar de la ventana como esta:

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); 

entonces creo que la respuesta es no , Oracle no admite esta (comprobado con 11gR2).

+0

¡Esto es lo que quería! Gracias. – Benoit

+0

@Benoit: pero lamentablemente ** no ** funciona en Oracle. –

+0

Acabo de notar que trato de usarlo. Muy malo. – Benoit

5

Puede utilizar la factorización subconsulta, también conocido como el con-cláusula:

(no probado)

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 

Regards,
Rob.

+0

Sí, pero aún así es un poco largo. Sin embargo, +1 por sugerir 'WITH' que es una gran palabra clave en Oracle. – Benoit

+0

Puede acortar la cláusula with para "seleccionar t. *, [Expresión de caso] como new_col7 de mytable t" y usar new_col7 en la consulta. –

+0

Aún así, no resolverá realmente el problema raíz: en su código todavía repite la parte '(partición por ...)'! – Benoit

Cuestiones relacionadas