# [26ai] SQL: Calendar functions/Aggregation Filters "CALENDAR"

En el artículo de hoy vamos a ver las **Calendar functions** en 26ai, diseñadas para simplificar la "vida" a los desarrolladores. Antes de su existencia, esto se resolvía con ingeniosas combinaciones usando **case**, **subquerys** o incluso condiciones de **agregación**. Haciendo todo ello, en algunos casos, una combinación perfecta para hacer consultas con cierta complejidad.

Estás extensiones formar parte de **SFA Initiative** (*Select for Analysis*), diseñadas para alinear más el Oracle SQL a los estándares.

A continuación puedes ver un gráfico ilustrativo de algunas de las distintas funciones que se han incorporado.

![](https://cdn.hashnode.com/uploads/covers/65605419d28f19cc44df7ef1/b70df231-6438-4b25-92b2-69a4f8dcfc2c.png align="center")

¿Cuándo debemos usarlas?

*   Cuando necesitamos agrupar en consultas analíticas por algún tipo de calendario descrito en el punto anterior.
    
*   Series temporales entre un rango de fechas.
    
*   Conversión del dato a nivel de columna.
    
*   Operaciones a nivel de un calendario, como agregar días o semanas.
    

Antes de empezar este laboratorio, debemos estar con la última versión de Oracle 23.26.2.

```sql
SQL> Select banner from v$version;

BANNER
--------------------------------------------------------------
Oracle AI Database 26ai Enterprise Edition Release 23.26.2.0.0 - Production
```

Para tener algo de información en nuestra PDB, vamos a cargar el schema de **HR**. Los scripts de este schema se encuentran en el github de **Oracle Sample Projects**.

Dejo aquí el enlace:

[Github Oracle Sample Projects](https://github.com/oracle-samples/db-sample-schemas)

El modelo ER es el siguiente:

![](https://cdn.hashnode.com/uploads/covers/65605419d28f19cc44df7ef1/c6bc7ce7-0509-452c-812b-b56115bcc7dd.png align="center")

## CALENDAR

### %\_Year

Vamos a ver como interpreta cada una de estas funciones usando la misma columna de tipo date sin necesidad de restructurar nada.

```sql
SQL> 
select EMPLOYEE_ID,
       calendar_year(START_DATE) calendar,
       fiscal_year(START_DATE)   fiscal,
       retail_year(START_DATE)   retail,
       START_DATE,END_DATE,JOB_TITLE,MIN_SALARY,MAX_SALARY
from HR.JOB_HISTORY NATURAL JOIN (Hr.JOBS)
  fetch first 10 rows only
```

![](https://cdn.hashnode.com/uploads/covers/65605419d28f19cc44df7ef1/42749812-26e8-437c-810c-ce3e344fe0ad.png align="center")

También pueden ser usadas para filtrar el resultado:

```sql
SQL> 
Select    EMPLOYEE_ID,START_DATE,END_DATE,JOB_TITLE,MIN_SALARY,MAX_SALARY
from HR.JOB_HISTORY NATURAL JOIN (Hr.JOBS)
where calendar_year(START_DATE) = 2011
  fetch first 10 rows only
```

![](https://cdn.hashnode.com/uploads/covers/65605419d28f19cc44df7ef1/89b742a1-4e94-4b06-8be2-e5b7f6810994.png align="center")

En este caso podíamos usar un ***Extract(Year from START\_DATE)*** y el resultado hubiera sido idéntico ¿verdad?

Pero mirando el ***explain plan*** de uno y otro, vemos alguna diferencia:

![](https://cdn.hashnode.com/uploads/covers/65605419d28f19cc44df7ef1/c3b72f0c-2f5f-46b2-b0cd-dd1e00e0fb62.png align="center")

![](https://cdn.hashnode.com/uploads/covers/65605419d28f19cc44df7ef1/f1bacd50-cc11-49f7-8307-305e29ee310a.png align="center")

Internamente el *extract* se resuelve con *INTERNAL\_FUNCTION* , mientras que el uso de la nueva función, el acceso es distinto. Curioso, en próximos artículos tendremos que profundizar este punto.

En el próximo artículo, veremos las funciones RETAIL y FISCAL.

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