none
Comparar dois Selects da mesma tabela... RRS feed

  • Pergunta

  • Boa tarde,

    Estou com o seguinte problema. Tenho uma tabela e nela precisava saber a diferença entre um select da mesma tabela e outro select. Por quê? Pois um select me retorna um registro a menos e queria incluir esse que faltava no outro select... Esse é o select que montei.             

             SELECT  USU_QTDRET, USU_CODPRO, USU_DATRET AS SALINI                                                                  
                  FROM USU_TE140IRT INNER JOIN E075PRO ON USU_TE140IRT.USU_CODPRO = E075PRO.CODPRO AND     
                                          USU_TE140IRT.USU_CODEMP =  E075PRO.CODEMP                   
                                    INNER JOIN E012FAM ON E012FAM.CODFAM = E075PRO.CODFAM AND              
                                                    E012FAM.CODEMP = E075PRO.CODEMP                  
                                    INNER JOIN E013AGP ON E013AGP.CODAGP = E075PRO.CODAGE AND              
                                                    E013AGP.CODEMP =  E075PRO.CODEMP                                                                                   
                                    WHERE USU_DATRET < '2013-01-01'                                                                                
                  ORDER BY  USU_TE140IRT.USU_DATRET DESC,
                            E075PRO.CODFAM,
                            USU_TE140IRT.USU_CODPRO ASC
      OBS: ESSE SELECT ME RETORNARIA 165 REGISTRO.

    -----------------------------------------------------------------------------------------------------------------------------------------

             SELECT  USU_QTDRET, USU_CODPRO, USU_DATRET AS SALINI                                                                  
                  FROM USU_TE140IRT INNER JOIN E075PRO ON USU_TE140IRT.USU_CODPRO = E075PRO.CODPRO AND     
                                          USU_TE140IRT.USU_CODEMP =  E075PRO.CODEMP                   
                                    INNER JOIN E012FAM ON E012FAM.CODFAM = E075PRO.CODFAM AND              
                                                    E012FAM.CODEMP = E075PRO.CODEMP                  
                                    INNER JOIN E013AGP ON E013AGP.CODAGP = E075PRO.CODAGE AND              
                                                    E013AGP.CODEMP =  E075PRO.CODEMP                                                                                   
                                    WHERE USU_DATRET = '2013-01-01'                                                                                
                  ORDER BY  USU_TE140IRT.USU_DATRET DESC,
                            E075PRO.CODFAM,
                            USU_TE140IRT.USU_CODPRO ASC
     OBS: ESSE ME RETORNARIA 166 REGISTRO. 

    --------------------------------------------------------------------------------------------------------------------------------------

    No final das contas eu precisaria que no primeiro select que retorna 165 fosse incluído o registro que falta do que retornou 166, o USU_DATRET varia. Se alguém puder me ajudar, ficarei grato. Eu estou aprendendo a utilizar o sql, não sei se é fácil, mas eu não estou conseguindo. 

    Att,



    terça-feira, 17 de março de 2015 17:50

Respostas

  • Boa tarde,

    Pelo que entendi agora acho que você pode tentar utilizar a query que você postou acima com algumas pequenas modificações:

    SELECT 
        t.USU_CODPRO,
        t.USU_DATRET,
        (SELECT TOP(1) s.USU_QTDRET 
         FROM USU_TE140IRT as s
         WHERE 
             s.USU_CODEMP = t.USU_CODEMP AND
             s.USU_CODPRO = t.USU_CODPRO AND
             s.USU_DATRET < '2013-01-01'
         ORDER BY 
             s.USU_DATRET DESC) AS SALINI                      
    FROM USU_TE140IRT as t
    WHERE
        t.USU_DATRET = '2013-01-01'

    Espero que ajude.


    Assinatura: http://www.imoveisemexposicao.com.br

    quinta-feira, 19 de março de 2015 17:59

Todas as Respostas

  • Gabriel,

    Você pode usar o EXCEPT para isso colocando a consulta que retorna 166 em primeiro. O Except irá retornar todos os registros que estão na consulta a esquerda (consulta de cima) que não existem na consulta da direita (consulta de baixo)

    SELECT  USU_QTDRET, USU_CODPRO, USU_DATRET AS SALINI                                                                  
    FROM USU_TE140IRT 
    INNER JOIN E075PRO ON USU_TE140IRT.USU_CODPRO = E075PRO.CODPRO AND  USU_TE140IRT.USU_CODEMP =  E075PRO.CODEMP                   
    INNER JOIN E012FAM ON E012FAM.CODFAM = E075PRO.CODFAM AND  E012FAM.CODEMP = E075PRO.CODEMP                  
    INNER JOIN E013AGP ON E013AGP.CODAGP = E075PRO.CODAGE AND  E013AGP.CODEMP =  E075PRO.CODEMP                                                       WHERE USU_DATRET = '2013-01-01'                                                                                
    ORDER BY  USU_TE140IRT.USU_DATRET DESC,E075PRO.CODFAM,USU_TE140IRT.USU_CODPRO ASC
    EXCEPT
    SELECT  USU_QTDRET, USU_CODPRO, USU_DATRET AS SALINI                                                                  
    FROM USU_TE140IRT INNER JOIN E075PRO ON USU_TE140IRT.USU_CODPRO = E075PRO.CODPRO AND  USU_TE140IRT.USU_CODEMP =  E075PRO.CODEMP                   
    INNER JOIN E012FAM ON E012FAM.CODFAM = E075PRO.CODFAM AND E012FAM.CODEMP = E075PRO.CODEMP                  
    INNER JOIN E013AGP ON E013AGP.CODAGP = E075PRO.CODAGE AND E013AGP.CODEMP =  E075PRO.CODEMP                                                        
    WHERE USU_DATRET < '2013-01-01'                                                                                
    ORDER BY  USU_TE140IRT.USU_DATRET DESC,E075PRO.CODFAM,USU_TE140IRT.USU_CODPRO ASC
      

    Se precisar de referência: https://msdn.microsoft.com/pt-br/library/ms188055.aspx

    Espero ter ajudado


    Mariana Del Nero /* Se a resposta foi útil, não esqueça de marcá-la */

    terça-feira, 17 de março de 2015 18:07
  • Boa tarde,

    Gabriel, o que essa linha a mais tem de diferente das outras 165?

    É algum USU_CODPRO que a primeira consulta não retorna?


    Assinatura: http://www.imoveisemexposicao.com.br

    terça-feira, 17 de março de 2015 18:07
  • Boa tarde, 

    Mensagem 156, Nível 15, Estado 1, Linha 8
    Incorrect syntax near the keyword 'EXCEPT'.

    terça-feira, 17 de março de 2015 18:38
  • Desculpe.

    Tira o ORDER BY da consulta...


    Mariana Del Nero /* Se a resposta foi útil, não esqueça de marcá-la */

    terça-feira, 17 de março de 2015 18:43
  • Boa tarde, 

    É complicado... Vamos lá 

    Preciso que emita o primeiro valor do SALDINIl encontrado antecedente ao dia inserido para consulta de todos os produto compreendidos na primeira data do ultimo lançamento.
    Explicação do por quê? Por que se o usuário pedi para puxar o relatório de segunda, ele não pode me mostrar referente ao domingo, mas sim da ultima vez lançada, que pode ter sido no sábado ou na sexta. Por isso o ultimo lançamento antecedente a data inserida. Assim aplica-se ao dia depois do feriado(DatRet < 2015-03-17)

    A diferença entre é que se eu peço para puxar o relatório de hoje(DatRet = 2015-03-17), o fechamento é só no final do dia, então ele vai me mostrar os últimos lançamentos dos produtos do estoque e se eu inserir um produto hoje e puxar o relatório amanhã, ele vai puxar somente o ultimo lançamento a partir da data que eu inserir. Enquanto que no outro curso sql estará dando 166 pois estará na data de hoje DatRet = 2015-03-17 e  outro estará DatRet < 2015-03-17

    Por isso queria comparar esse dois, pois se houver diferença, ele acrescente no sql (DatRet < 2015-03-17).

    Ficou claro? k 

    OBS: As datas podem mudar, e assim a quantidade de registro, mas a lógica é a mesma. 


    terça-feira, 17 de março de 2015 18:49
  • Retirei, dois pontos que notei. 

    1º O valor permaneceu o mesmo, mesmo invertendo a ordem; 

    2º Preciso do order by.

    Muito obrigado pela resposta rápida, 

    Att.



    terça-feira, 17 de março de 2015 19:06
  • Vamos ver se entendi corretamente...

    Você quer que a linha do dia 17/03/2015 seja retornada somente se o USU_CODPRO não tiver nada antes do dia 17/03/2015?


    Assinatura: http://www.imoveisemexposicao.com.br

    terça-feira, 17 de março de 2015 19:32
  • Não, o sql sempre retornará os valor antecedente a data definida. Tentativa de explicação: 

    O usuário vai puxar um relatório com a data de hoje, se o sql estiver com a data atual não irá ter nada, porque só irá ter informação amanhã, porque hoje não fechou o período. Entretanto, se eu deixar para puxar somente o dia antecedente, ocorrerá isso, se amanhã ele puxar o relatório de hoje e se hoje foi inserido um novo produto, ele não mostrará no relatório com a data de hoje esse produto, só no relatório com a data de amanhã. Por isso, necessito que ao formar a Query com a condição de trazer os produtos antecedentes a data inserida ele verifica se na data inserida há algum produto diferente da ultima data encontrada, se houver, ele insere junto na pesquisa. 

    Ficou claro? 

    Att.




    terça-feira, 17 de março de 2015 19:43
  • Não seria o caso de deixar o filtro da data com o sinal de menor e igual?

    WHERE USU_DATRET <= '2015-03-17'

    A query passaria a retornar o produto cadastrado no próprio dia 17/03, a partir do momento em que a linha foi inserida na tabela (pelo que entendi após o fechamento), independente do dia em que a query foi executada (no próprio dia 17/03 ou depois).

    Espero que ajude.


    Assinatura: http://www.imoveisemexposicao.com.br

    terça-feira, 17 de março de 2015 20:04
  • Não, porque se analisar, o valor do USU_QTDRET varia por dia, se você colocar o operador <=, ele primeiro vai selecionar todos os produtos que sejam iguais ou menor, dependendo da ordenação ele vai ordenar pela data ou codpro, enfim, vai ficar se for por ordenação por codpro, vai ficar dois codpro, um do dia atual e outro do dia atual, se for pela data DESC, vai ficar do maior pra o menor... Resumindo, quando fosse imprimir não seria o valor real, seria o valor totalmente diferente, porque o valor tem que ser do primeiro que anteceder a data inserida. Essa parte de estoque é meio complicada, mas a melhor solução seria ele unir somente a diferença do dia selecionado pelo usuário com o select antecedente. Aí que teria o valor real USU_QTDRET por causa do DATRET < '????-??-??'   e teria a junção se houver dos produtos novos inserido DATRET = '????-??-??'.

    Se tiver uma forma de pegar aqueles dois sql's que referenciei lá em cima, e fazer a comparação e a diferença ser mostrada no sql que tem DATRET < '2013-01-01'. Seria a minha solução k

    Att.  

     
    terça-feira, 17 de março de 2015 20:39
  • Ainda está meio confuso..., acho melhor você postar um exemplo com uma pequena amostra de dados (uns 3 produtos) e o respectivo resultado esperado para facilitar o entendimento da questão.

    Assinatura: http://www.imoveisemexposicao.com.br

    terça-feira, 17 de março de 2015 21:10
  • Bom dia,

    As Querys são aquelas duas que enviei lá em cima. Elas são a mesma pesquisa, a diferença é que preciso do < em uma e na outra do =, questão um pouco complexa, tentei explicar mais não deu muito certo. Enfim, preciso que os resultado que for gerado na query que tenha o operador = seja mostrado na Query que tem o operador <, mas só os resultados diferentes.

    Vou puxar um relatório da data 01-03-2015(SIMULANDO UM USUÁRIO QUALQUER) 

    Exemplo: <    Ele vai pegar o primeiro valor antecedente a mim.

    COD    ValorInicial    Data

    78          25                  2015-01-02

    44          25                  2015-01-02

    12          25                  2015-01-02

    Resultado 3----------------------------------------------------------------------------------------------------------------------------------------------------------------

    Só que no dia 03-01-2015 foi inserido um outro produto, se o usuário fizer essa pesquisa hoje referenciando aquela data, vai mostrar o mesmo resultado a cima. Por causa do <. Ai que vem o outro operador =. Veja só: 

    Exemplo: =    Ele vai pegar todos os valores da data que o usuário inseriu, no caso 01-03-2015

    COD    ValorInicial    Data

    78          40                 2015-01-03

    44          00                  2015-01-03

    12          05                  2015-01-03

    28          15                  2015-01-03

    Resultado: 4----------------------------------------------------------------------------------------------------------------------------------------------------------------

    Notou o que falei, preciso desse novo registro "28" inserido na consulta do menor <. Porém se eu fizer <=, olha como ele me apresentaria. 

    COD    ValorInicial    Data

    78          40                 2015-01-03

    44          00                  2015-01-03

    12          05                  2015-01-03

    28          15                  2015-01-03

    78          25                  2015-01-02

    44          25                  2015-01-02

    12          25                  2015-01-02

    Resultado: 7----------------------------------------------------------------------------------------------------------------------------------------------------------------

    E na verdade eu precisaria de algo assim: 

    78          25                  2015-01-02

    44          25                  2015-01-02

    12          25                  2015-01-02

    28          15                  2015-01-03

    Resultado: 4----------------------------------------------------------------------------------------------------------------------------------------------------------------

    Deu para compreender? kk 

    quarta-feira, 18 de março de 2015 13:19
  • Bom dia,

    Acho que ficou mais fácil assim, mas ainda ficou uma dúvida...

    Considerando que a tabela possua as 7 linhas do resultado com menor e igual que você postou acima, a consulta deveria retornar qual resultado com o dia 04/01/2015? Nesse dia todas as 7 linhas atendem a condição do filtro só com o menor, sem o igual.


    Assinatura: http://www.imoveisemexposicao.com.br

    quarta-feira, 18 de março de 2015 13:39
  • Usuário pediu para puxar a data 04/01/2015

    Agora entra a condição, se a data a atual fosse 04/01/2015 ele retornaria 4 resultados, porque você lembra que no dia 03/01/2015 ele achou somente 4 e você lembra que eu disse assim, retorne o primeiro antecedente a mim, por isso ele não retornaria dia 02/01/2015, somente primeiro antecedente encontrado, neste caso dia 03. 

    Mas, se a data atual fosse dia 18/03/2015 e ele pedisse um relatório do dia 04/01/2015 e nesse dia um produto novo foi inserido(isso nem sempre acontece mas pode), ele deverá mostrado além de mostrar o primeiro antecedente a mim como o novo produto do dia 04/01/2015. 

    Por isso preciso de uma Query que mostre além do primeiro antecedente, quanto o novo produto(se tiver) nessa consulta do primeiro antecedente.  Resumindo: na Query < deverá conter se tiver o resultado novo da query =, mas só o novo. 

    quarta-feira, 18 de março de 2015 13:54
  • Experimente fazer um teste para ver se é obtido o resultado desejado:

    SELECT
        C.USU_QTDRET, 
        E075PRO.USU_CODPRO, 
        C.USU_DATRET AS SALINI
    FROM E075PRO 
    CROSS APPLY
    (
        SELECT TOP(1) 
            USU_TE140IRT.USU_QTDRET,
            USU_TE140IRT.USU_DATRET
        FROM USU_TE140IRT 
        WHERE 
            USU_TE140IRT.USU_CODPRO = E075PRO.CODPRO AND
            USU_TE140IRT.USU_CODEMP = E075PRO.CODEMP AND
            USU_TE140IRT.USU_DATRET <= '2015-01-04'
        ORDER BY
            USU_DATRET DESC 
    ) AS C
    INNER JOIN E012FAM 
        ON 
            E012FAM.CODFAM = E075PRO.CODFAM AND
            E012FAM.CODEMP = E075PRO.CODEMP
    INNER JOIN E013AGP 
        ON 
            E013AGP.CODAGP = E075PRO.CODAGE AND
            E013AGP.CODEMP = E075PRO.CODEMP
    ORDER BY
        SALINI DESC,
        E075PRO.CODFAM,
        USU_CODPRO

    Espero que ajude.


    Assinatura: http://www.imoveisemexposicao.com.br

    quarta-feira, 18 de março de 2015 14:18
  • Não obtevi: Exemplo do resultado: 

    COD    ValorInicial    Data

    78          40              2015-01-03

    44          00                  2015-01-03

    12          05                  2015-01-03

    28          15                  2015-01-03

    78          25            2015-01-02

    44          25                  2015-01-02

    12          25                  2015-01-02

    Enquanto queria: Exemplo:

    78          25             2015-01-02

    44          25                  2015-01-02

    12          25                  2015-01-02

    28          15                 2015-01-03

    Resultado: 4----------------------------------------------------------------------------------------------------------------------------------------------------------------

    Vamos lá, o que preciso da data pedida é somente a diferença da ultima data encontrada.

    Exemplo: No dia 04/01/2015 eu tenho 10 resultados. O usuário pediu o relatório do dia 04/01/2015, porém o relatório vai buscar o valor do ultimo lançamento, que no caso, pode ou não ser do dia anterior, vamos dizer que seja dia 03/01/2015, mas aqui eu tenho 9. Esses 9 vão se igual aos 9 que tem no dia 04/01/2015 em Cod/nome/descrição... Mas a diferença vai ser os valores$$ contidos em cada data. Enfim, preciso de uma Query que me mostre o valores do ultimo lançamento e me diz, os últimos lançamentos anteriores a data que você colocou são esses, ops mas na data que você colocou existe um novo diferente dos últimos lançamentos e eu também vou acrescentar ao resultado. É isso que preciso.


    quarta-feira, 18 de março de 2015 14:56
  • Acredito que a query que sugeri deveria retornar apenas uma linha para cada produto.

    Confira a sugestão anterior com alguns ajustes (no nome da coluna CodPro e no Order By) na página abaixo:

    http://sqlfiddle.com/#!6/b5486/13

    Espero que ajude.


    Assinatura: http://www.imoveisemexposicao.com.br

    quarta-feira, 18 de março de 2015 17:13
  • A query que você mandou ela não retorna o produto que difere em relação ao antecedente. Acho que do jeito que eu quero está meio complicado. Antes eu tinha montado uma query que retornava uma de cada vez, mas não conseguir modifica-lá pra retornar todos os produtos. Basicamente era assim: 

    SELECT USU_TE140IRT.USU_DATRET,                                                                                          
            (SELECT TOP 1 USU_QTDRET FROM USU_TE140IRT                                                      
             WHERE USU_DATRET < '2013-01-01' AND                                                       
    				       USU_CODPRO = '???' ORDER BY USU_DATRET DESC) AS SALINI                      
            FROM USU_TE140IRT                                                                               
            WHERE USU_TE140IRT.USU_DATRET = '2013-01-01' AND                                           
                  USU_TE140IRT.USU_CODEMP = ? AND                                                           
                  USU_TE140IRT.USU_CODPRO = '????'             
     

    O problema dessa daí é como disse, só retorna um resultado de cada vez, porque é consulta por produto e data. Mas quando eu retiro a necessidade de definir o produto e deixo somente a data, ele me retorna a data 2013-01-01 e o USU_QTDRET referente a essa data. E o que precisava seria a data, mas com o USU_QTDRET do ultimo antecedente. Do mesmo modo que funciona referenciando o produto e a data.  

    OBS: O seu retornou o  USU_DATRET junto com USU_QTDRET refente ao mesmo dia, e não USU_DATRET do dia referido. Porém com o USU_QTDRET do dia anterior.

    Acho que vou procurar uma outra forma kk está difícil. 



    quinta-feira, 19 de março de 2015 11:18
  • Desculpe mas não entendi o problema.

    Você pode postar uma outra amostra de dados de exemplo e o respectivo resultado esperado para demonstrar o problema?

    Ou então ajustar a amostra de dados do link que postei.


    Assinatura: http://www.imoveisemexposicao.com.br

    quinta-feira, 19 de março de 2015 15:14
  • Gapimex, boa tarde!

    Vou tentar o mais claro possível agora na explicação, vamos lá: 

    A query, que preciso que ela puxe os produtos de hoje com o valor antecedente, porque tem que puxar o ultimo lançamento. Vou dar um exemplo:

    Quero puxar os produtos da data 05/02/2016(EXEMPLO), vamos dizer que naquele dia me retorne 20 resultados. Ok? Agora vem a questão, ele tem que me retornar a quantidade de produto daquele dia, mas o campo USU_QTDRET tem que ser do ultimo lançamento. Entendeu? 

    Vamos de novo, o campo USU_DATRET tem que retornar a quantidade de produto desse dia mesmo, e o campo USU_QTDRET tem que retorna o ultimo lançamento desse produto. Ficou claro agora? Vou tentar exemplificar mais com um exemplo visível que vou criar: 

    USU_DATRET              USU_QTDRET 
    2016-02-05                 28
    ..........                .......

    A coluna USU_DATRET retornar os produtos da data que usuário chamou no relatório, no caso 05/02/2016 e a coluna USU_QTDRET retorna os valores dos últimos lançamentos dos produtos que foram listado na data 2016-02-05. Logo o valor que está no campo USU_QTDRET não será o valor que consta no dia 2016-02-05, mas sim do ultimo lançamento, que pode ser 2016-02-04 ou 2016-02-03 ou 206-02-02....Isso depende de quando foi o lançamento do ultimo produto. 


    Espero que tenha sido claro, se quiser posso tentar de novo k Muito obrigado por está ajudando.


    quinta-feira, 19 de março de 2015 17:11
  • Boa tarde,

    Pelo que entendi agora acho que você pode tentar utilizar a query que você postou acima com algumas pequenas modificações:

    SELECT 
        t.USU_CODPRO,
        t.USU_DATRET,
        (SELECT TOP(1) s.USU_QTDRET 
         FROM USU_TE140IRT as s
         WHERE 
             s.USU_CODEMP = t.USU_CODEMP AND
             s.USU_CODPRO = t.USU_CODPRO AND
             s.USU_DATRET < '2013-01-01'
         ORDER BY 
             s.USU_DATRET DESC) AS SALINI                      
    FROM USU_TE140IRT as t
    WHERE
        t.USU_DATRET = '2013-01-01'

    Espero que ajude.


    Assinatura: http://www.imoveisemexposicao.com.br

    quinta-feira, 19 de março de 2015 17:59
  • Valeu Gapimex, você me ajudou muito! 

    Só fiz algumas alterações para autentificar melhor os dados, uns inner join's. Mas utilizei praticamente a mesma base. 

    Muito obrigado, tomei um tempão seu, mas foi, valeu ai de novo! 
    quinta-feira, 19 de março de 2015 19:54