none
sub query ou inner join RRS feed

  • 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.

    segunda-feira, 13 de fevereiro de 2012 11:11

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
    segunda-feira, 13 de fevereiro de 2012 16:45

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
    segunda-feira, 13 de fevereiro de 2012 16:45
  • 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
    segunda-feira, 13 de fevereiro de 2012 18:35