Fazer uma PerguntaFazer uma Pergunta
 

PerguntaWhere no AS

  • terça-feira, 3 de novembro de 2009 0:53Oraculum Medalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     Contém Código
    Preciso de retornar do banco todos os seriais que se encontram disponiveis na empresa e que tenham pelo menos 150 dias da data da compra, a minha tabela está assim:


    Tabela Series
    filial - produto - serie - ordem - descricao - sequencia - disponivel (True ou False)

    Essa tabela vai guardando as informações dos seriais, tipo cada movimentação que fazemos num serial ele inseri uma nova linha para ele, então temos aqui compras, transferencias de filiais, vendas (torna disponivel em false) etcsss


    Bem consegui fazer a seguinte query:



    SELECT     Filial, Produto, Serie, Disponivel,
                              (SELECT     Data
                                FROM          Entradas
                                WHERE      (Sequencia =
                                                           (SELECT     Sequencia
                                                             FROM          Series AS series2
                                                             WHERE      (Produto = series.produto) AND (Serie = series.serie) AND (Ordem = 0)))) AS DataCompra
    FROM         Series
    GROUP BY Filial, Produto, Serie, Disponivel, Ordem
    HAVING      (Ordem =
                              (SELECT     MAX(Ordem) AS Expr1
                                FROM          Series AS Series1
                                WHERE      (Filial = Series.Filial) AND (Produto = Series.Produto) AND (Serie = Series.Serie))) AND (Filial = 1) AND (Disponivel = 'True') AND (DataCompra < '6/2/2009')
    

    No select eu criei uma coluna chamada DataCompra que pega o dia da entrada do serial na ordem 0 (primeira movimentação do serial na empresa significa que ele foi comprado. Acontece que queria fazer um filtro na query que pegasse os registro com data menor que 'x' mas o sql me retorna a sequinte mensagem de error:

    Invalid column name 'DataCompra'

    Isso porque essa coluna realmente não existe no banco é só fruto de um select para pegar a informacao de outra tabela.

    Bem agora segue-se minhas duvidas:

    1 - É possivel fazermos where nos campos 'AS'?

    2 - Você me aconselham fazer uma query grande assim com varios select ou devo fazer isso via programação, por ex: pego todos os produtos retorno numa lista, depois pego os serias ativos deles retorno em outra lista depois vou varrendo a lista de seriais e verifico quais estao via codigo com mais de 150 dias de compra?  Pergunto se eh melhor fazer via query ou código pois uma vez me disseram que via query deixa as coisas muito mais rapidas na hora da execução, então procure fazer o maximo via query.


    Desde já agradeço a atenção de todos.

Todas as Respostas

  • terça-feira, 3 de novembro de 2009 12:00Junior Galvão - MVPMVPMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     
    Oraculum,

    Vamos lá:

    1 - É possivel fazermos where nos campos 'AS'?

    Eu nunca tentei fazer isso, como a coluna não exista na tabela com certeza o SQL Server vai gerar um erro, sendo que, o comando AS tem como função dar nomes virtuais as colunas durante a execução da query.

    2 - Você me aconselham fazer uma query grande assim com varios select ou devo fazer isso via programação, por ex: pego todos os produtos retorno numa lista, depois pego os serias ativos deles retorno em outra lista depois vou varrendo a lista de seriais e verifico quais estao via codigo com mais de 150 dias de compra?  Pergunto se eh melhor fazer via query ou código pois uma vez me disseram que via query deixa as coisas muito mais rapidas na hora da execução, então procure fazer o maximo via query.

    O processamento em query normalmente é mais rápido, mas logicamente isso depende de algumas consideraçãoes.

    Definir o que seria melhor para sua necessidade fica um pouco complicado pois não conhecemos o seu cenário, em várias situações aqui na empresa eu prefiro utilizar o processamento direto no SQL Server e enviar para aplicação somente o resultado.
    Pedro Antonio Galvão Junior - MVP - Windows Server System - SQL Server/Coordenador de Projetos/DBA
  • terça-feira, 3 de novembro de 2009 12:06Anderson.dpa Medalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     
    Bom dia

    Caso você esteja utilizando o SQL Server 2008 recomendo alterar as tabelas derivadas por CTE´s (Commom Table Expression)



    Anderson - DBA/MCP/MCTS/MCITP/MCT - Sua pergunta foi respondida ? Marque-a como tal! www.myspace.com/andersondpa
  • terça-feira, 3 de novembro de 2009 12:30Junior Galvão - MVPMVPMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     

    Anderson,

    Eu concordo com você ai desta forma poderiamos pensar no SQL Server 2000 em utilizar Derived Table!!!


    -- SubQuery Derived Table (SQL Server 7 e demais)
    Declare @T1 Table (Valor1 Int)

    Insert Into @T1 Values (1)
     
    Select Valor1, Valor2, (Valor1+Valor2) as Total
    from (
    Select Valor1,
    (Select 1 from @T1) as Valor2
    From @T1) As Q

    -- SubQuery Derived Table (SQL Server 7 e demais)
    select Conta, Descricao, VDebito, VCredito, (VCredito - VDebito) as SaldoFinal
    FROM (
    Select Conta,Descricao,
    (select SUM(Valor) From LancaContabil Where Debito = Conta) as VDebito,
    (select SUM(Valor) From LancaContabil Where Credito = Conta) as VCredito
    From PlanoContabil) As Q

    -- Common Table Expression (2005 e superiores)
    ;WITH Q (Conta, Descricao, VDebito, VCredito)
    As (
    Select Conta,Descricao,
    (select SUM(Valor) From LancaContabil Where Debito = Conta) as VDebito,
    (select SUM(Valor) From LancaContabil Where Credito = Conta) as VCredito
    From PlanoContabil)
    select Conta, Descricao, VDebito, VCredito, (VCredito - VDebito) as SaldoFinal
    FROM Q


    Pedro Antonio Galvão Junior - MVP - Windows Server System - SQL Server/Coordenador de Projetos/DBA
  • quarta-feira, 4 de novembro de 2009 3:12Oraculum Medalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     

    Eu conseguir fazer o filtro no da data da compra mais pra isso preciso fazer aquele select que fiz para pegar a data da compra novamente no where:

     

    (SELECT Data
    FROM Entradas
    WHERE (Sequencia =
    (SELECT Sequencia
    FROM Series AS series2
    WHERE (Produto = series.produto) AND (Serie = series.serie) AND (Ordem = 0)))) AS DataCompra

     

     

    Vocês acham vantagem fazer dessa forma ou em questão de desempenho seria melhor jogar o resultado sem o filtro da data da compra numa lista fazer um loop nela e ir verificando quais os produtos que atendem e joga-los numa nova lista, para poder aí sim popular no grid?

  • quarta-feira, 4 de novembro de 2009 11:55Junior Galvão - MVPMVPMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     
    Oraculum,


    Sugiro utilizar o plano de execução para iniciarmos a análise de como o SQL Server esta processando esta query;
    Pedro Antonio Galvão Junior - MVP - Windows Server System - SQL Server/Coordenador de Projetos/DBA
  • sexta-feira, 6 de novembro de 2009 3:30Oraculum Medalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     
    Veja como ficou meu plano de execução para essa query .


    Acho que a mais complicada foi o select dentro da entrada com 27% como eu nunca fiz isso antes não sei se está bom ou ruim :(


    Desde já agradeço a atenção.




  • sexta-feira, 6 de novembro de 2009 11:50Alexandre VM Medalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     
    Bom dia Oraculum,

    Realmente, o "Series2" está consumindo bastante, mas o que vejo de mais preocupante é o fato de ele estar realizando 2 Table Scans. No Series2 e Series. Provavelmente esta tabela nem chave primária (índice Clustered) tem. 

    Então, recomendaria você avaliar a criação de um índice CLUSTERED nessa tabela e também ajustar a consulta incluindo índices NONCLUSTERED para melhorar o acesso ao dado conforme for necessário.


    Qualquer dúvida / problema, estamos a disposição.


    Abraço!!!

    Classifiquem as respostas. O Fórum agradece!!