Mesma subquery rodando várias vezes

Dúvidas, dicas e truques de SQL, Select, Update, Delete, cláusulas, operações com joins, Funções em SQLs, etc
vrbrant
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 4
Registrado em: Ter, 04 Set 2012 2:27 pm

E ai pessoal beleza?
Tenho uma query que executa uma determinada subquery várias vezes.
Cada resultado dessa subquery passa por um CONCAT específico. (poderia ser qualquer outra função, não importa)
Depois todos os resultados dos CONCAT são unido com UNION, gerando o resultado final.

Vejam:

Selecionar tudo

Select a, b, c, d from(
    (
        Select a, b, c, CONCAT(d, e) as d from (
            Select * from tabela where data BETWEEN '01/12/2000' and '05/03/2013'
        )
    )
    union
    (
        Select a, b, c, CONCAT(e, f) as d from (
            Select * from tabela where data BETWEEN '01/12/2000' and '05/03/2013'
        )
    )
    union
    (
        Select a, b, c, CONCAT(f, g) as d from (
            Select * from tabela where data BETWEEN '01/12/2000' and '05/03/2013'
        )
    )
    union
    (
        Select a, b, c, CONCAT(g, h) as d from (
            Select * from tabela where data BETWEEN '01/12/2000' and '05/03/2013'
        )
    )
    union
    (
        Select a, b, c, CONCAT(h, i) as d from (
            Select * from tabela where data BETWEEN '01/12/2000' and '05/03/2013'
        )
    )
    ... mais alguns unions ...
)
Reparem que a mesma subquery " Select * from tabela where data BETWEEN '01/01/2000' and '01/01/2013' " é executada várias vezes e ela sozinha já traz muitos resultados (dados de 13 anos).
Só que ela está rodando N vezes (1 vez para cada caso do CONCAT). Isto faz com que a query completa demore muito!

O que pode ser feito nesse caso para que esta subquery não rode tantas vezes desnecessariamente?
Algo que faça ela rodar somente uma vez e seu result seja reaproveitado nas outras querys de fora?

Já tentei colocar essa subquery em uma view e colocar a chamada da view no lugar da subquery. Mas isso não fez diferença alguma no tempo de execução já que a view rodaria a cada chamada do mesmo jeito. :?

Me dêm uma força.

Abraços!
Trevisolli
Moderador
Moderador
Mensagens: 2016
Registrado em: Qua, 12 Jan 2005 3:25 pm
Localização: Araraquara - SP
Abraço,

Trevisolli
OCA Oracle PL/SQL Developer Certified Associate
OCP Oracle Forms Developer Certified Professional
Araraquara-SP

Brother, boa tarde.

Não testei aqui o comando, mas, uma dica seria utilizar o WITH, para recuperar 1 vez só as informações e, depois utilizá-las...

Veja se funciona utilizando o código abaixo como um exemplo:

Selecionar tudo

WITH tabela_principal AS 
    (select a, b, c, d, e, f, g, h, i, j from tabela where data BETWEEN '01/12/2000' and '05/03/2013' )
  SELECT a, b, c, CONCAT(e, f) as d FROM tabela_principal 
  UNION 
  SELECT a, b, c, CONCAT(f, g) as d from tabela_principal
  UNION 
  ... 
Qualquer coisa, manda pra gente.

Abraço,

Trevisolli
vrbrant
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 4
Registrado em: Ter, 04 Set 2012 2:27 pm

Trevisolli,

Cara esse WITH matou a charada!
Muito bom, eu não conhecia essa.

Ficou assim:

Selecionar tudo

With X as (
    Select * from tabela where data BETWEEN '01/12/2000' and '05/03/2013'
)
Select a, b, c, d from(
    (
        Select a, b, c, CONCAT(d, e) as d from X
    )
    union
    (
        Select a, b, c, CONCAT(e, f) as d from X
    )
    union
    (
        Select a, b, c, CONCAT(f, g) as d from X
    )
    union
    (
        Select a, b, c, CONCAT(g, h) as d from X
    )
    union
    (
        Select a, b, c, CONCAT(h, i) as d from X
    )
    ... mais alguns unions ...
)
Caso resolvido.

Valeu!
Trevisolli
Moderador
Moderador
Mensagens: 2016
Registrado em: Qua, 12 Jan 2005 3:25 pm
Localização: Araraquara - SP
Abraço,

Trevisolli
OCA Oracle PL/SQL Developer Certified Associate
OCP Oracle Forms Developer Certified Professional
Araraquara-SP

Que bom que deu certo brother.
Dessa forma, você lê tua tabela principal, com os parâmetros de data uma única vez.
Precisando, conte com a gente.
Abraço,
Avatar do usuário
fbifabio
Moderador
Moderador
Mensagens: 199
Registrado em: Ter, 22 Fev 2011 1:51 pm
Localização: São Paulo - SP
Contato:
Fábio Prado
www.fabioprado.net

Só para complementar o assunto, a cláusula WITH é genéricamente conhecida como CTE (Commom Table Expression) e faz parte do padrão ANSI SQL 99.

Para mais informações, leia o artigo: http://www.fabioprado.net/2010/10/claus ... eries.html.

[]s
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 11 visitantes