Pular para o conteúdo
  • Este tópico contém 6 respostas, 3 vozes e foi atualizado pela última vez 10 anos, 11 meses atrás por Avatar de Gustavo S CoelhoGustavo S Coelho.
Visualizando 7 posts - 1 até 7 (de 7 do total)
  • Autor
    Posts
  • #106185
    Avatar de Gustavo S CoelhoGustavo S Coelho
    Participante

      Olá pessoal, estou precisando fazer uma consulta onde os dados sejam retornados desta projeção mensurando apenas o registro mais recente cadastrado e para isso estou
      tentando usar um subselect com a função max, porém a consulta continua trazendo mais de um registro.

      O Banco de dados é o SQL Server 2012.

      Segue os dados retornados e a consulta aplicada

      Qualquer sugestão será bem vinda.

      NUM_ORCAMENTO, CD_ITEM_PEDIDO, CD_PRODUTO, NUM_PEDIDO, QTD_ITEM, VIG_GARANTIA_ESTENDIDA, CD_TRANSACAO_GARANTECH, DT_TRANSACAO

      957517 1 8259 0 1 NULL 1 2011-01-24 15:21:16.617
      957517 1 8259 0 1 NULL 2 2011-01-24 15:39:53.990

      SELECT TOP 10
      ITEM_PED.NUM_ORCAMENTO AS NUM_ORCAMENTO,
      ITEM_PED.CD_ITEM_PEDIDO AS CD_ITEM_PEDIDO,
      ITEM_PED.CD_PRODUTO AS CD_PRODUTO,
      ITEM_PED.NUM_PEDIDO AS NUM_PEDIDO,
      ITEM_PED.QTD_ITEM AS QTD_ITEM,
      TGRE.VIG_GARANTIA_ESTENDIDA,
      TRANS.CD_TRANSACAO_GARANTECH,
      TRANS.DT_TRANSACAO
      FROM TAB_ITEM_PEDIDO ITEM_PED
      LEFT JOIN TAB_ITEM_PEDIDO_GARANTIA ITEM_PED_GAR
      ON (ITEM_PED.NUM_ORCAMENTO = ITEM_PED_GAR.NUM_ORCAMENTO
      AND ITEM_PED.CD_ITEM_PEDIDO = ITEM_PED_GAR.CD_ITEM_PEDIDO
      AND ITEM_PED_GAR.NUM_ORCAMENTO = 957517
      )
      JOIN TAB_TRANSACAO_GARANTECH TRANS
      ON (ITEM_PED.NUM_ORCAMENTO = TRANS.NUM_ORCAMENTO
      AND ITEM_PED.CD_ITEM_PEDIDO = TRANS.CD_ITEM_PEDIDO

      AND TRANS.NUM_ORCAMENTO IN (
      SELECT NUM_ORCAMENTO FROM TAB_TRANSACAO_GARANTECH
      WHERE EXISTS(
      SELECT MAX(DT_TRANSACAO), NUM_ORCAMENTO FROM TAB_TRANSACAO_GARANTECH
      WHERE NUM_ORCAMENTO = 957517 GROUP BY NUM_ORCAMENTO
      )
      )

      --AND TRANS.FL_ATIVO = 'S' --AND TRANS.FL_ATIVO = '"+TransacaoGarantechVO.FLAG_ATIVO+"'
      --AND TP_TRANSACAO = 'S' --AND TP_TRANSACAO = '"+TransacaoGarantechVO.TP_TRANSACAO_ATIVA+
      )
      LEFT JOIN TAB_GARANTECH_RETORNO_ENQUADRAMENTO TGRE
      ON(TGRE.cd_produto = ITEM_PED.CD_PRODUTO)
      LEFT JOIN TAB_GARANTECH_TABELA_PRECO AS TGTP
      ON (TGTP.cd_plano_garantech=TGRE.cd_plano_garantech
      AND TGTP.vig_garantia_estendida=TGRE.vig_garantia_estendida
      AND TGTP.vig_garantia_fab_pecas =TGRE.vig_garantia_fab_pecas
      AND TGTP.tp_garantia=TGRE.tp_garantia
      AND TGTP.tp_registro=TGRE.tp_registro
      )
      WHERE ITEM_PED.NUM_ORCAMENTO = 957517
      AND ITEM_PED.CD_ITEM_PEDIDO = 1
      GROUP BY ITEM_PED.NUM_ORCAMENTO,
      ITEM_PED.CD_ITEM_PEDIDO,
      ITEM_PED.CD_PRODUTO,
      ITEM_PED.NUM_PEDIDO,
      ITEM_PED.QTD_ITEM,
      TGRE.VIG_GARANTIA_ESTENDIDA,
      --TRANS.DT_TRANSACAO,
      TRANS.CD_TRANSACAO_GARANTECH,
      TRANS.DT_TRANSACAO;

      #106186
      Avatar de rmanrman
      Participante

        @Gustavo S Coelho

        Olhando a consulta ficou difícil entender o que você quer retornar.

        Mas o uso do EXISTS, funciona da seguinte forma:


        SELECT NUM_PEDIDO
        FROM PEDIDO P
        WHERE EXITS(
        SELECT 1
        FROM ITEM_PEDIDO IP
        WHERE IP.PEDIDO_ID = P.ID
        );

        Repare que eu ligo o SELECT de fora com o SELECT de entre através da PK/FK. Essa consulta retorna pedidos que possuem itens.

        Agora a função de agrupamento:


        SELECT CLIENTE_ID,MAX(DATA_COMPRA) ULTIMA COMPRA
        FROM VENDA
        GROUP BY CLIENTE_ID;

        Essa consulta vai trazer a data da última compra agrupado por CLIENTE_ID. Repare que a função de agrupamento sempre vem acompanhada do GROUP BY.

        #106187
        Avatar de Gustavo S CoelhoGustavo S Coelho
        Participante

          @rman

          A consulta não é muito complicada, preciso retornar as seguintes colunas:

          ITEM_PED.NUM_ORCAMENTO AS NUM_ORCAMENTO,
          ITEM_PED.CD_ITEM_PEDIDO AS CD_ITEM_PEDIDO,
          ITEM_PED.CD_PRODUTO AS CD_PRODUTO,
          ITEM_PED.NUM_PEDIDO AS NUM_PEDIDO,
          ITEM_PED.QTD_ITEM AS QTD_ITEM,
          TGRE.VIG_GARANTIA_ESTENDIDA,
          TRANS.CD_TRANSACAO_GARANTECH,
          TRANS.DT_TRANSACAO

          O problema é que existem registros duplicados quanto a NUM_ORCAMENTO na tabela TAB_TRANSACAO_GARANTECH porém com horários diferentes para a coluna DT_TRANSACAO
          neste caso eu usei um subselect na junção da tabela informando para trazer apenas o registro mais atual com a função max. Mesmo assim não está funcionando, continua trazendo mais de um registro quando eu preciso apenas do mais atual.
          Tentei remover esta o subselect da junção e colocar na cláusula where da consulta principal mas mesmo assim não funcionou.

          JOIN TAB_TRANSACAO_GARANTECH TRANS
          ON (ITEM_PED.NUM_ORCAMENTO = TRANS.NUM_ORCAMENTO
          AND ITEM_PED.CD_ITEM_PEDIDO = TRANS.CD_ITEM_PEDIDO

          AND TRANS.NUM_ORCAMENTO IN (
          SELECT NUM_ORCAMENTO FROM TAB_TRANSACAO_GARANTECH
          WHERE EXISTS(
          SELECT MAX(DT_TRANSACAO), NUM_ORCAMENTO FROM TAB_TRANSACAO_GARANTECH
          WHERE NUM_ORCAMENTO = 957517 GROUP BY NUM_ORCAMENTO
          )
          )

          #106188
          Avatar photoRegis Araujo
          Participante

            @Gustavo

            Boa tarde!

            O Exists não funciona igual ao IN, então não adianta vc colocar o MAX na clausula do select, pois ele vai usar apenas boolean se existir relação entre a tabela referenciada e a tabela do exists, irá retornar informações.

            Tanto que costuma-se usar o “.. exists (select 1 from tabela a where a.campo = out.campo) ..”…

            Para você pegar apenas o ultimo registro, você irá precisar usar o MAX como parâmetro de comparação na query ao invés do exists informado…

            Ex:

            ” SELECT NUM_ORCAMENTO FROM TAB_TRANSACAO_GARANTECH TBOUT WHERE TBOUT.DT_TRANSACAO = (SELECT MAX(TBIN.DT_TRANSACAO) FROM TAB_TRANSACAO_GARANTECH TBIN WHERE TBOUT.NUM_ORCAMENTO = TBIN.NUM_ORCAMENTO)
            AND TBOUT.NUM_ORCAMENTO = 957517 ”

            Como você havia informado que existe o mesmo número de orçamento mas com datas diferentes, este relacionamento irá retornar apenas o NUM_ORCAMENTO com data maior…

            Espero que tenha lhe ajudado..

            A Disposição.

            Regis Araujo

            #106189
            Avatar de rmanrman
            Participante

              JOIN TAB_TRANSACAO_GARANTECH TRANS
              ON (ITEM_PED.NUM_ORCAMENTO = TRANS.NUM_ORCAMENTO
              AND ITEM_PED.CD_ITEM_PEDIDO = TRANS.CD_ITEM_PEDIDO
              AND TRANS.NUM_ORCAMENTO = (
              SELECT TOP 1 NUM_ORCAMENTO FROM TAB_TRANSACAO_GARANTECH
              WHERE NUM_ORCAMENTO = 957517 ORDER BY DT_TRANSACAO DESC
              )

              Agora ficou mais claro, como é SQL Server, a solução fica TOP1 + ORDER BY DESC.

              #106190
              Avatar photoRegis Araujo
              Participante

                @Gustavo

                Segue um exemplo para demonstrar o que eu passei antes..!!

                16:20:18 GPOREGIS.REGIS>> alter session set nls_date_format = 'DD/MM/YYYY HH24:MI:SS';

                Session altered

                16:20:43 GPOREGIS.REGIS>> SELECT * FROM TESTEDATA;

                     A B
                

                     1 17/12/2013 16:35:32
                     1 17/12/2013 16:35:37
                     1 17/12/2013 16:35:42
                     2 17/12/2013 16:35:46
                

                16:21:02 GPOREGIS.REGIS>> select * from testedata xx where xx.b = (select max(b) from testedata zz where zz.a = xx.a);

                     A B
                

                     1 17/12/2013 16:35:42
                     2 17/12/2013 16:35:46
                

                16:21:28 GPOREGIS.REGIS>>

                Abraços.!

                Regis Araujo

                #106192
                Avatar de Gustavo S CoelhoGustavo S Coelho
                Participante

                  Pessoal,

                  Obrigado pela ajuda, testei aqui com todas as formas sugeridas e ainda não funcionou.
                  Na verdade o problema está no modelo, pois o agrupamento está trazendo registros duplicados pois existem valores em algumas colunas na relação com outras tabelas que é diferente para cada registro então apenas criterizar o max ou o orderby por uma coluna ainda não resolve o problema pois ainda existem outras.

                  Mas neste caso é algo que não cabe ao fórum, é uma questão de análise de dados a se tratar.

                  Mais uma vez obrigado pela ajuda.

                Visualizando 7 posts - 1 até 7 (de 7 do total)
                • Você deve fazer login para responder a este tópico.
                plugins premium WordPress