SELECT, COM VARIOS SUBSELECTS, OU TABELA TEMPORARIA

Dúvidas, dicas e truques de SQL, Select, Update, Delete, cláusulas, operações com joins, Funções em SQLs, etc
alvear
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 4
Registrado em: Qua, 02 Dez 2009 11:15 am
Localização: São Paulo - SP

Bom dia colegas!

Ao deparar com um problema, para elaborar um relatório, tive que fazer um Select um pouco complexo, com Vários SubSelcts, lendo apenas duas tabelas, porem, varias vezes.
Agora estou com uma duvida.
Qual solução seria mais rápida e funcional?
O Select, ou criar um Tabela Temporária em tempo de execução, realizando a leitura das duas tabelas, um Insert, e outra leitura na tebela temporária, com algumas rotinas de repetição.

Agradeço a todos pela ateção!
E desejo um Bom Dia!
diegolenhardt
Moderador
Moderador
Mensagens: 1177
Registrado em: Qui, 15 Out 2009 10:28 am
Localização: Recife

acredito que indexar as duas tabelas de acordo com o necessário, seja a melhor solução, do que ter que preencher toda vez a temporary table.

minha idéia
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Se o select tem várias subqueries com consulta à mesma tabela, o ideal é tentar cortar fora essa gordura. O melhor jeito de fazer isso é usando analytic functions com windowing e referência às outras linhas que você precisa, sem precisar dar múltiplos scans e self-joins, que saem muito mais caro em termos de desempenho.

Se você quiser postar um exemplo de estrutura das tabelas, dados de insert e saída de exemplo do SQL que você precisa, e ainda sua query atual para sabermos como deve ser o output, podemos ajudar mais.
alvear
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 4
Registrado em: Qua, 02 Dez 2009 11:15 am
Localização: São Paulo - SP

então fsitja,

Esse select, retorna um registro de uma tabela, que retorna um ultimo registro de outra tabela.Essas tabelas estao ligadas por um id. Tem mais outros parametros, mas o mais dificil, foi fazer esta ligação.
Só que o BD utilizado foi o MySQL.
não sei o que é analytic functions com windowing, se alguém puder me esclarecer, ficarei grato!
Estou começando agora na área de Oracle, quer dizer, ainda não comecei, estou realizando o curso de formação Oracle.

Selecionar tudo

SELECT 	cadprocesso.idProcesso,cadprocesso.Processo, cadprocesso.NroVara, cadprocesso.Vara, 
		cadprocesso.idCliente, cadprocesso.idReu, cadcli.RazSoc, cadreu.Nome,
		(SELECT idProcOcor
		 FROM 	cadprococor 
		 WHERE 	idprococor = (SELECT MAX(idprococor) 
		 					  FROM 	cadprococor 
		 					  WHERE 	cadprocesso.idProcesso = cadprococor.idProcesso)) AS idProcOcor,
		(SELECT idProcesso
		 FROM 	cadprococor 
		 WHERE 	idprococor = (SELECT MAX(idprococor) 
		 					  FROM 	cadprococor 
		 					  WHERE 	cadprocesso.idProcesso = cadprococor.idProcesso)) AS idProcesso,
		(SELECT idocorrencia 
		 FROM 	cadprococor 
		 WHERE 	idprococor = (SELECT MAX(idprococor) 
		 					  FROM 	cadprococor 
		 					  WHERE 	cadprocesso.idProcesso = cadprococor.idProcesso)) AS idOcorrencia,
		(SELECT DATA
		 FROM 	cadprococor 
		 WHERE 	idprococor = (SELECT MAX(idprococor) 
		 					  FROM 	cadprococor 
		 					  WHERE 	cadprocesso.idProcesso = cadprococor.idProcesso)) AS DATA,
		(SELECT Ocorrencia1 
		 FROM 	cadprococor 
		 WHERE 	idprococor = (SELECT MAX(idprococor) 
		 					  FROM 	cadprococor 
		 					  WHERE 	cadprocesso.idProcesso = cadprococor.idProcesso)) AS Ocorrencia1,
		(SELECT Ocorrencia2 
		 FROM 	cadprococor 
		 WHERE 	idprococor = (SELECT MAX(idprococor) 
		 					  FROM 	cadprococor 
		 					  WHERE 	cadprocesso.idProcesso = cadprococor.idProcesso)) AS Ocorrencia2
FROM 	cadprocesso
JOIN 	cadreu ON cadreu.idReu = cadprocesso.idReu
JOIN 	cadcli ON cadcli.idCliente = cadprocesso.idCliente AND cadprocesso.idcliente = 1
WHERE 	(SELECT idProcOcor
		 FROM 	cadprococor 
		 WHERE 	idprococor = (SELECT MAX(idprococor) 
		 					  FROM 	cadprococor 
		 					  WHERE 	cadprocesso.idProcesso = cadprococor.idProcesso)) <> '' 
AND (SELECT Ocorrencia1 
		 FROM 	cadprococor 
		 WHERE 	idprococor = (SELECT MAX(idprococor) 
		 					  FROM 	cadprococor 
		 					  WHERE 	cadprocesso.idProcesso = cadprococor.idProcesso)) LIKE '%15/01%'
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Blza saquei, mas você está rodando esse SQL no Oracle agora ou no MySQL? Porque no MySQL não tem função analítica.
Aguardo a resposta antes de pensar numa solução, só para garantir.

Enquanto isso, uma leitura sobre funções analíticas:
http://download.oracle.com/docs/cd/E118 ... ons004.htm
alvear
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 4
Registrado em: Qua, 02 Dez 2009 11:15 am
Localização: São Paulo - SP

É MySQL fsitja.
burga
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Qui, 26 Nov 2009 1:05 pm
Localização: SP

Oi alvear, analisando sua consulta eu consegui cortar bastante coisa.
Transformei todas as subquerys em uma só e joguei na cláusula from...
Acho que ficou mais legível e deve melhorar um pouco a performance também.

Selecionar tudo

SELECT cadprocesso.idprocesso,
  cadprocesso.processo,
  cadprocesso.nrovara,
  cadprocesso.vara,
  cadprocesso.idcliente,
  cadprocesso.idreu,
  cadprocesso.uf,
  cadprocesso.cidade,
  cadcli.razsoc,
  cadreu.nome,
  ultimo.idprococor,
  ultimo.idprocesso,
  ultimo.idocorrencia,
  ultimo.data,
  ultimo.ocorrencia1,
  ultimo.ocorrencia2
FROM cadprocesso,
    (SELECT idprococor,
     idprocesso,
     idocorrencia,
     data,
     ocorrencia1,
     ocorrencia2
   FROM cadprococor
   WHERE idprococor IN
    (SELECT MAX(idprococor)
     FROM cadprococor
     GROUP BY idprocesso)
  ) ultimo,
  cadagen JOIN cadreu ON cadreu.idreu = cadprocesso.idreu
  JOIN cadcli ON cadcli.idcliente = cadprocesso.idcliente AND cadprocesso.idcliente = '001'
WHERE ultimo.idprocesso = cadprocesso.idprocesso
 AND ultimo.idprocor <> ''
 AND ultimo.ocorrencia1 LIKE '%01/2010 %'
 AND (ultimo.idocorrencia = cadagen.parametro1
 OR ultimo.idocorrencia = cadagen.parametro2); 
Não testei então pode dar algum erro bobo de sintaxe, mas daí você já consegue arrumar...
Rozan Malta
Rank: Estagiário Júnior
Rank: Estagiário Júnior
Mensagens: 1
Registrado em: Qui, 11 Fev 2010 10:05 am
Localização: BA

Estou criando uma query onde preciso exibir os valores diferenciados em campos diferentes, no entanto tais valores são provenientes da mesma tabela... a diferença é somente um campo data...
Vejam a query:

Selecionar tudo

SELECT faconcad.fantasia as convenio, SUM (fafatcad.valor_guia) FT,
(
SELECT SUM (fafatcad.valor_guia)
FROM faremcad,fafatcad,fafatprd,faprdcad,faconcad
WHERE fafatcad.remessa = faremcad.remessa
  AND fafatcad.cod_con = faremcad.cod_con
  AND fafatcad.fatura = fafatprd.fatura
  AND fafatprd.cod_prd = faprdcad.codigo
  AND fafatcad.cod_con = faconcad.cod_con
  AND faremcad.data_emiss >= '01/08/2009'
  AND faremcad.data_emiss <= '31/08/2009'
) RM
FROM faremcad, fafatcad, faconcad
WHERE 
fafatcad.data_emiss >= '01/08/2009' 
AND fafatcad.data_emiss <= '31/08/2009' 
AND fafatcad.remessa = faremcad.remessa 
AND fafatcad.cod_con = faconcad.cod_con 
GROUP BY faconcad.fantasia,TO_CHAR (fafatcad.data_emiss, 'MM/YYYY'),faconcad.cod_con

Quando executo as query's separadamente, elas exibem o resultado que eu quero... só que preciso do resultado numa tabela só.

alguém sabe o que posso fazer?

Grato.
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Rozan, não deu para entender o que você quer obter na query. Se for possível, por favor poste um exemplo do output de cada uma das queries separadamente e depois poste um output desejado para a query "unificada", mostrando como ficariam os dados delas quando juntas.

Se der, ajuda também mostrar dados de exemplo para suas 4 tabelas e as estruturas de colunas delas (create tables e inserts de dados para podermos executar algo aqui).
Responder
  • Informação
  • Quem está online

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