# [26ai] Funciones Analíticas-Qualify

En el artículo de hoy, vamos a ver otro gran cambio para hacernos la vida más fácil a los DBA y desarrolladores, es la clausula **qualify**. Pero, ¿Para que sirve?

Los que hacemos diariamente uso de las funciones analíticas utilizando la función ***Row_Number*** para quedarnos con el mejor resultado dentro de un grupo de datos, acabamos definiendo una ***subquery***.

Está clausula filtra los resultados de las funciones analíticas dentro de la misma sentencia, sin necesidad de definir ***subquerys***, consiguiendo una mayor eficiencia.

Un ejemplo, supongamos que estamos consultando las vistas de AWR, y queremos consultar para el mes actual, las consultas con mayor *BUFFER_GETS_DELTA* a nivel de snap.

En versiones anteriores a 26ai tendríamos que definirlo del siguiente modo:

```sql
SQL> 
With My_Snaps As (
SELECT snap_id,INSTANCE_NUMBER,begin_interval_time
  FROM dba_hist_snapshot 
 WHERE extract(Year from begin_interval_time) = extract(year from sysdate)
   And extract(Month from begin_interval_time) = extract(Month from sysdate)
)
SELECT  
        METRICA,
        day,
        db_name,
        Instance,
        SQL_ID,
        plan_hash_value,
        INST,
        EXEC,
        rows_,
        elap,
        BUFFER_GETS_DELTA
 FROM (
   SELECT 
        'GETS' AS METRICA,
        extract(day from begin_interval_time) day,
        Sys_Context('USERENV', 'DB_NAME') db_name,
        Sys_Context('USERENV','INSTANCE_NAME') Instance,
        a.SNAP_ID,
        a.SQL_ID,
        a.plan_hash_value,
        a.INSTANCE_NUMBER INST,
        a.EXECUTIONS_DELTA EXEC,
        a.ROWS_PROCESSED_DELTA rows_,
        a.ELAPSED_TIME_DELTA elap,
        a.BUFFER_GETS_DELTA,
        ROW_NUMBER() OVER (
          PARTITION BY a.SNAP_ID 
          ORDER BY a.BUFFER_GETS_DELTA DESC nulls last) As ORDEN  
    FROM DBA_HIST_SQLSTAT a,My_Snaps b
    WHERE 1 = 1 
      And A.Snap_Id = b.Snap_Id
      And A.INSTANCE_NUMBER = B.INSTANCE_NUMBER
      And PARSING_SCHEMA_NAME != 'SYS'    
      )
   Where ORDEN = 1
    fetch first 20 rows Only;
```

Con este resultado:

![](https://cdn.hashnode.com/uploads/covers/65605419d28f19cc44df7ef1/8bce842c-96e1-44ea-b5f6-f4704ba580cb.png align="center")

En **26ai** podemos conseguir el mismo resultado usando la cláusula **QUALIFY**.

```sql
SQL> 

With My_Snaps As (
SELECT snap_id,INSTANCE_NUMBER,begin_interval_time
  FROM dba_hist_snapshot 
 WHERE extract(Year from begin_interval_time) = extract(year from sysdate)
   And extract(Month from begin_interval_time) = extract(Month from sysdate)
)
   SELECT 
        'GETS' AS METRICA,
        extract(day from begin_interval_time) day,
        Sys_Context('USERENV', 'DB_NAME') db_name,
        Sys_Context('USERENV','INSTANCE_NAME') Instance,
        a.SNAP_ID,
        a.SQL_ID,
        a.plan_hash_value,
        a.INSTANCE_NUMBER INST,
        a.EXECUTIONS_DELTA EXEC,
        a.ROWS_PROCESSED_DELTA rows_,
        a.ELAPSED_TIME_DELTA elap,
        a.BUFFER_GETS_DELTA,
        ROW_NUMBER() OVER (
          PARTITION BY a.SNAP_ID 
          ORDER BY a.BUFFER_GETS_DELTA DESC nulls last) As ORDEN  
    FROM DBA_HIST_SQLSTAT a,My_Snaps b
    WHERE A.Snap_Id = b.Snap_Id
      And A.INSTANCE_NUMBER = B.INSTANCE_NUMBER
      And PARSING_SCHEMA_NAME != 'SYS'  
    qualify ORDEN = 1
    fetch first 20 rows Only;
```

Con este resultado:

![](https://cdn.hashnode.com/uploads/covers/65605419d28f19cc44df7ef1/43c8ca42-11ba-4e5b-a0e4-b58e7e6c35e9.png align="center")

Como podemos observar ambos output son idénticos sin necesidad de hacer una subquery, mejorando al eficiencia así como la legibilidad de la misma.

Espero que os guste. ¡Nos vemos en el próximo artículo!
