GPO ( Grupo de Profissionais Oracle )
A maior comunidade Oracle do Brasil !

Tunando Queries com cláusula WITH

Queries com cláusula WITH

Este artigo tem como objetivo esclarecer os conceitos e citar exemplos práticos da Cláusula WITH conhecida como CTE (Commom table expression). As formas abaixo são úteis no dia a dia de cada Developer/DBA.

A CTE é muito utilizada a fim de tunar queries, basicamente ela é uma instrução SELECT que cria uma espécie de tabela temporária (um result set) com seu resultado. Então em cima desse resultado efetuamos novas instruções SQL e isso facilita muito consultas complicadas.

Estrutura de uma CTE

WITH cte [ ( column_name [,…n] ) ]
AS (
CTE_query
)
SELECT
FROM CTE;

Digamos que seu gestor pede um relatório para descobrir quem são os funcionários mais antigos de cada departamento atualmente. Na tabela Employees nós temos o código do departamento e também a data de contratação.

Com a cláusula WITH nós conseguimos em uma única query “rankear” todos os funcionários por departamento, e fazer o select apenas em cima desse resultado visto que a cláusula with cria uma espécie de result set temporário na sua execução.

with cte as (
select employee_id
    , department_id
    , hire_date
    , RANK() OVER (PARTITION BY department_id ORDER BY hire_date) rank_contratacao
from hr.employees
)
select
      cte.employee_id
    , e.first_name
    , cte.department_id
    , cte.hire_date
from cte
join hr.employees e on e.employee_id = cte.employee_id
where rank_contratacao = 1
order by department_id;

Com a query acima, nós tivemos o seguinte resultado:

Outra forma de conseguirmos o mesmo resultado seria utilizando uma subquery, no entanto, menos performática no caso devido a ser uma subquery correlacionada (mutiple rows) ou seja, são executadas linha a linha sobre a query da esquerda (outer query).

select jh1.employee_id
    , e.first_name
    , jh1.department_id
    , jh1.hire_date
from hr.employees jh1
join hr.employees e on e.employee_id = jh1.employee_id
where not exists (select 1
                  from hr.employees jh2
                  where jh2.department_id = jh1.department_id
                  and jh1.hire_date > jh2.hire_date)
order by jh1.department_id;

Com a query acima nós tivemos o seguinte resultado:

Concluímos que com a utilização da clásula WITH temos diversas vantagens como deixar a query mais legível, aumento de performance visto que a CTE reduz o uso de recursos do BD, além de facilitar muito a criação de queries recursivas e queries com window function(row_number(), rank(), dense_rank()).

Share

You may also like...

Deixe um comentário

O seu endereço de e-mail não será publicado.