Usuário com melhor resposta
sub query ou inner join

Pergunta
-
Ola, pessoal
tenho 1 duvida que gostaria de saber qual "a melhor forma" , dentro das melhores praticas ,
-----
declare @MesVcto integer; declare @AnoVcto integer;
set @MesVcto = 1; set @AnoVcto = 2012;
SELECT fin.CodBancos, (select bco.descricao from tab_bancos bco where bco.cod = fin.codbancos) as DescricaoBanco
, sum(fin.valor) as ValorTotal, sum(fin.valorpago) as ValorRecebido
FROM TAB_FinanceiroTitulos AS fin
WHERE fin.Tipo = 'R'
AND (YEAR(fin.DataVencimento) = @AnoVcto or @AnoVcto is null)
AND (month(fin.DataVencimento) = @MesVcto or @MesVcto is null)
AND cc.CodCentrosCusto in (2,3,13,7)
group by fin.CodBancos
order by fin.CodBancos
----é uma consulta bem simples, retorna o valor total de titulos a Receber, por Banco.
Sobre a subconsulta para pegar o banco. O que eu preciso da tabela de Bancos é realmente apenas a descrição, e mais nada.
O correto seria fazer como fiz (sub consulta), ou seria melhor fazer um INNER JOIN com a tabela de Bancos?
Dai ficaria assim:
select fin.CodBancos, bco.Descricao.......
INNER JOIN TAB_Bancos bco on bco.cod = fin.codBancos
group by fin.CodBancos, bco.Descricao
Então, como da pra ver, o "problema", no inner join com a tabela de bancos, é que tenho um group by fin.CodBancos, e para usar o campo da descricao, teria que coloca-la no group by. Isso é meio estranho, ou da pra fazer assim? não interfere muito na performance?
Quais são as "melhores praticas" nesse caso?
Eu sei que há outras soluções mais robustas, exemplo usar tabela derivadas... mas como é algo simples, eu não faria isso, nesse caso.Julio C.
Respostas
-
Julio,
Ao meu ver, não existindo o certo e o errado, e sim o coerente! veja. sendo simples voce pode fazer de qualquer uma das formas, levando em consideração que seu sistema SEMPRE manipulara a mesma quantidade de registros, isso devido a grande performance das máquinas e dos bancos de dados,
Utilizando a segunda opção com INNER JOIN, inicialmente pode ser mais custoso, pois o banco fará mais operações internas ( como Join e Group By ) já na SubQuery o banco fará 2 Selects. como disse embora mais custoso, quando for estiver manipulando uma grande quantidade de registros ficará evidente que utiliza-se de uma SubQuery não é a melhor opção.
Obs.: Não existe o certo ou errado quando funciona, existe o Coerente para sua necessidade, e ela pode ser modificado no crescer da sua aplicação, fazer agora ou depois?
- Marcado como Resposta Julio Costi segunda-feira, 13 de fevereiro de 2012 18:35
Todas as Respostas
-
Julio,
Ao meu ver, não existindo o certo e o errado, e sim o coerente! veja. sendo simples voce pode fazer de qualquer uma das formas, levando em consideração que seu sistema SEMPRE manipulara a mesma quantidade de registros, isso devido a grande performance das máquinas e dos bancos de dados,
Utilizando a segunda opção com INNER JOIN, inicialmente pode ser mais custoso, pois o banco fará mais operações internas ( como Join e Group By ) já na SubQuery o banco fará 2 Selects. como disse embora mais custoso, quando for estiver manipulando uma grande quantidade de registros ficará evidente que utiliza-se de uma SubQuery não é a melhor opção.
Obs.: Não existe o certo ou errado quando funciona, existe o Coerente para sua necessidade, e ela pode ser modificado no crescer da sua aplicação, fazer agora ou depois?
- Marcado como Resposta Julio Costi segunda-feira, 13 de fevereiro de 2012 18:35
-
Ola, Diogo
Concordo plenamente com oq vc fala, em relação ao "certo x errado".
A minha duvida era MAIS em relação ao "group by" codigo e descrição.. é uma coisa que parece estranha, redundante...
Uma forma mais elegante de fazer isso, eu acho que seria usar uma tabela derivada... Assim faria o agrupamento apenas no COD do banco, que é o que preciso, e não preciso fazer a subconsulta.
ficaria:
SELECT bco.cod, bco.descricao as DescricaoBanco, fin.valor as ValorTotal, fin.valorpago as ValorRecebido
FROM (select fin.codBancos, sum(fin.valor) as Valor, sum(fin.valorpago) as ValorPago
from TAB_FinanceiroTitulos fin
WHERE fin.Tipo = 'R' AND (YEAR(fin.DataVencimento) = @AnoVcto or @AnoVcto is null)
AND (month(fin.DataVencimento) = @MesVcto or @MesVcto is null)
AND cc.CodCentrosCusto in (2,3,13,7)group by fin.codBancos) fin
inner join TAB_Bancos bco on fin.codbancos = bco.cod
order by bco.cod
.
.
.
ou, ainda, daria para usar TCE, tambem ficaria segmentado e visualmente limpo.
... mas não é o caso, neste exemplo é relativamente simples, e não vai trazer problemas qualquer q seja destas formas que eu faça. É apenas uma duvida/constatação sobre o agrupamento por codigo e descrição, parece uma gambiarra, que seria necessario caso usasse inner join sem o a tabela derivada.
- Editado Julio Costi segunda-feira, 13 de fevereiro de 2012 18:39