Publicidade

Multiplos ‘With’

Olá pessoal.

Venho aqui com uma dica bem útil de SQL, que é quando trabalhamos com o “WITH”.

O “WITH” é muito útil, pois ele permite externar uma subconsulta como se esta fosse uma tabela, podendo ser novamente filtrada e se for o caso, com outros “WITH” e assim por diante.

Vamos a um exemplo simples do uso do “WITH”:

Imaginemos a seguinte tabela de usuários:

Tabela: Usuario
Campo: ID as integer
Campo: NOME as varchar(20)
Campo: LOGIN as varchar(8)
Campo: EMAIL as varchar(30)

Com os seguintes dados:
ID   NOME           LOGIN          SEM NOME
1    Juca Legal     juca.legal     juca.legal@email.com
2    Pedro Bacana   pedro.bacana   pedro.bacan@email.com
3    Suzan Suzana   suzan.suzana   
4    Janaina Ina    janaina.ina    janaina.ina@email.com
5    Lucas Louco    lucas.louco

 Vamos supor que eu queira filtrar todos os usuários que possuam e-mail e listar os e-mails deles, posso fazer tudo em uma única query, mas vou dividir em duas para exemplificar o “WITH”.

Então primeiro, vou filtrar todos os usuários, retornando “SIM” para os que possuem e-mail e “NAO” para os que não possuem e-mail cadastrado, dessa forma:

select ID,
       NOME,
       LOGIN,
       iif(EMAIL = '' or EMAIL = null,'NAO','SIM')
from Usuario

Esse select irá retornar os seguintes dados:
ID   NOME           LOGIN          SEM NOME
1    Juca Legal     juca.legal     SIM
2    Pedro Bacana   pedro.bacana   SIM
3    Suzan Suzana   suzan.suzana   NAO
4    Janaina Ina    janaina.ina    SIM
5    Lucas Louco    lucas.louco    NAO

 Com o “select” acima, filtramos todos usuários, informando na última coluna “SIM” e “NAO”.

Agora vamos transformar este select em uma tabela temporária com o “WITH”, que vou chamar de “EMAIL_SN” e vamos selecionar todos dados desta tabela temporária:

with EMAIL_SN as
(select ID as ID,
        NOME as NOME,
        LOGIN as LOGIN,
        iif(EMAIL = '' or EMAIL = null,'NAO','SIM') as SN
 from Usuario)

 select *
 from EMAIL_SN

ID   NOME           LOGIN          SN
1    Juca Legal     juca.legal     SIM
2    Pedro Bacana   pedro.bacana   SIM
3    Suzan Suzana   suzan.suzana   NAO
4    Janaina Ina    janaina.ina    SIM
5    Lucas Louco    lucas.louco    NAO

O “WITH” é usado seguido do nome da nossa tabela temporária: “EMAIL_SN”, após o nome usamos o comando “as” e em seguida colocamos nosso select entre parenteses “(select ID …)”, porém neste caso, todas as colunas do select dentro do parenteses do “with” precisam possuir nomes de colunas, como vocês podem notar, usei o mesmo nome dos campos, somente o último campo, que não possuía nome por ser um “iif”, eu nomeei de “SN”.

O “select” logo após o “with” retorna todos os dados da tabela temporária “EMAIL_SN”, com os mesmo dados, mas com os nomes de colunas que colocamos dentro do “select” do “with”.

Agora, vamos usar a nova coluna nomeada “SN” para fazer uma consulta de todos os usuários que possuem e-mail, com um “join”, e exibir seus nomes e e-mails:

with EMAIL_SN as
(select ID as ID,
        NOME as NOME,
        LOGIN as LOGIN,
        iif(EMAIL = '' or EMAIL = null,'NAO','SIM') as SN
 from Usuario)

 select US.Nome,
        US.Email
 from Usuarios US
 inner join EMAIL_SN EM on (US.Login = EM.Login and EM.SN = 'SIM')

Resultado:
NOME           EMAIL
Juca Legal     juca.legal@email.com
Pedro Bacana   pedro.bacan@email.com
Janaina Ina    janaina.ina@email.com

 Vejam que o “with” gerou os resultados com uma tabela temporária, fazendo um pré-filtro que em seguida utilizamos com um “join” para filtrar os usuários com e-mail e exibir Nome e Email de cada um. No exemplo acima, a consulta retornada é a do “select” logo abaixo do “with”, pois o “select” contido “with” ficam contidos na tabela temporária “EMAIL_SN”.

Usando o “WITH”, podemos fazer o mesmo com mais dados, vamos por exemplo, filtrar além dos usuários que possuem e-mail, filtrar somente o Pedro, usando outro “WITH” em conjunto com o primeiro:

with EMAIL_SN as
(select ID as ID,
        NOME as NOME,
        LOGIN as LOGIN,
        iif(EMAIL = '' or EMAIL = null,'NAO','SIM') as SN
 from Usuario),
EMAIL_PEDRO as
(select ID as ID,
        NOME as NOME,
        LOGIN as LOGIN
 from Usuario
 where NOME = 'Pedro Bacana')

select US.Nome,
       US.Email
from Usuarios US
inner join EMAIL_SN EM on (US.Login = EM.Login and EM.SN = 'SIM')
inner join EMAIL_PEDRO EP on (US.Login = EP.Login)

O resultado será:
NOME           EMAIL
Pedro Bacana   pedro.bacan@email.com

 Nos exemplos acima usei o “WITH” para exemplificar, pois nestas consultas eles não são necessários, mas acredito que tenha conseguido ser suficientemente didático.

Espero que tenha sido útil, e em caso de dúvidas, postem nos comentários.

T+

Deixe um comentário

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