Select - Dúvidas com Ultimo registro

27/12/2013

Bom Dia Pessoal,
Tenho o seguinte SELECT:

SELECT DISTINCT (HistFilaConj.Idhist)
HistFilaConj.Conjugacao,
CAST(LEFT(Ofs.OP,(CHARINDEX('-',Ofs.OP,1)-1))AS INTEGER) AS NumeroPedido,
CAST(SUBSTRING(Ofs.OP,7,2)AS INTEGER) AS ItemOP,
CONVERT(varchar(10), Inicio, 103) DataInicio,
CAST(CONVERT(float,Inicio)AS INTEGER) AS HoraInicio,
CONVERT(varchar(10),DataExpedicao, 103) AS DataExpedicao,
CAST(CONVERT(float,DataExpedicao)AS INTEGER) AS HoraExpedicao,
OFs.Op,
HistFilaConj.Boletim,
HistFilaConj.Lote,


FROM Trimbox.dbo.HistFilaConj
INNER JOIN OFS ON Ofs.OP = HistFilaConj.OF1
WHERE
OFS.OP LIKE '%[0-9][0-9][0-9][0-9][0-9]-[0-9][0-9]/%'
AND OFS.OP LIKE '%[0-9][0-9][0-9][0-9]-[0-9]%'
AND OFS.OP LIKE '%[0-9][0-9]-[0-9]%'
AND OFS.OP LIKE '%[0-9][0-9][0-9]-[0-9]%'
AND OFS.OP IS NOT NULL
AND HistFilaConj.Inicio IS NOT NULL
AND DataExpedicao IS NOT NULL
AND HistFilaConj.Inicio IS NOT NULL
AND DataExpedicao IS NOT NULL
AND HistFilaConj.Boletim IS NOT NULL
AND HistFilaConj.Lote IS NOT NULL
AND HistFilaConj.Conjugacao IS NOT NULL


GROUP BY
HistFilaConj.IDHist,
HistFilaConj.Inicio,
OFs.OP,
OFs.DataExpedicao,
HistFilaConj.Lote,
HistFilaConj.Boletim

ORDER BY HistFilaConj.IdHist DESC

Preciso que ele me traga somente o ultimo registro do campo IDHIST.

Fazendo um SELECT DISTINCT somente neste campo ele funciona, mas com os outros campos ele traz várias vezes o mesmo ID.

Como devo proceder?

Marcio Morando

Respostas

27/12/2013

Fabiano Carvalho

Existe outras saidas...

with ultimo as (
select max(HistFilaConj.Idhist) from HistFilaConj
)
SELECT DISTINCT (HistFilaConj.Idhist )
HistFilaConj.Conjugacao,
CAST(LEFT(Ofs.OP,(CHARINDEX('-',Ofs.OP,1)-1))AS INTEGER) AS NumeroPedido,
CAST(SUBSTRING(Ofs.OP,7,2)AS INTEGER) AS ItemOP,
CONVERT(varchar(10), Inicio, 103) DataInicio,
CAST(CONVERT(float,Inicio)AS INTEGER) AS HoraInicio,
CONVERT(varchar(10),DataExpedicao, 103) AS DataExpedicao,
CAST(CONVERT(float,DataExpedicao)AS INTEGER) AS HoraExpedicao,
OFs.Op,
HistFilaConj.Boletim,
HistFilaConj.Lote,


FROM Trimbox.dbo.HistFilaConj
INNER JOIN OFS ON Ofs.OP = HistFilaConj.OF1
WHERE
OFS.OP LIKE '%[0-9][0-9][0-9][0-9][0-9]-[0-9][0-9]/%'
AND OFS.OP LIKE '%[0-9][0-9][0-9][0-9]-[0-9]%'
AND OFS.OP LIKE '%[0-9][0-9]-[0-9]%'
AND OFS.OP LIKE '%[0-9][0-9][0-9]-[0-9]%'
AND OFS.OP IS NOT NULL
AND HistFilaConj.Inicio IS NOT NULL
AND DataExpedicao IS NOT NULL
AND HistFilaConj.Inicio IS NOT NULL
AND DataExpedicao IS NOT NULL
AND HistFilaConj.Boletim IS NOT NULL
AND HistFilaConj.Lote IS NOT NULL
AND HistFilaConj.Conjugacao IS NOT NULL
and HistFilaConj.Idhist = select(id from ultimo)
GROUP BY
HistFilaConj.IDHist,
HistFilaConj.Inicio,
OFs.OP,
OFs.DataExpedicao,
HistFilaConj.Lote,
HistFilaConj.Boletim

ORDER BY HistFilaConj.IdHist DESC
Responder Citar

27/12/2013

Alex Lekao

eu normalmente qdo preciso de algo parecido uso uma subselect com o campo que quero e no where da subselect igualo um campo unico da subselect e da select principal.

para mim tem sempre dados certo assim... rsrsr

na vdd nao sei fazer diferente... pronto falei... rsrsrsrsr
Responder Citar

27/12/2013

Fabiano Carvalho

nesse caso acho que poderia fazer

usando o having...

having max(id) = id
Responder Citar

27/12/2013

Marcio Morando

Da erro de sintaxe incorreta sublinhando o ultimo depois do with e o and HistFilaConj.Idhist = select(HistFilaConj.Idhist from ultimo)
Responder Citar

27/12/2013

Marcio Morando

Fabiano, consegui arrumar o código que me passou, mas aparece este erro:

A subconsulta retornou mais de 1 valor. Isso não é permitido quando a subconsulta segue um =, !=, <, <= , >, >= ou quando ela é usada como uma expressão.
Responder Citar

27/12/2013

Fabiano Carvalho

Mostre como ficou, é que voce ta usando = em uma subconsulta que retorna mais de um valor, por esse motivo ocorre o erro.
Responder Citar

27/12/2013

Marcio Morando

Tentei fazer daquela forma não deu certo. Agora tentei dessa maneira aqui também, e mesmo assim ele continua trazendo registros duplicados.

SELECT 1,1,MAX(HistFilaConj.IdHist),
CAST(LEFT(Ofs.OP,(CHARINDEX('-',Ofs.OP,1)-1))AS INTEGER) AS NumeroPedido,
CAST(SUBSTRING(Ofs.OP,7,2)AS INTEGER) AS ItemOP,
CONVERT(varchar(10), Inicio, 103) DataInicio,
CAST(CONVERT(float,Inicio)AS INTEGER) AS HoraInicio,
CONVERT(varchar(10),DataExpedicao, 103) AS DataExpedicao,
CAST(CONVERT(float,DataExpedicao)AS INTEGER) AS HoraExpedicao,
'InformacoesVindasdaTabelaHISTFILACONJ_OF1',
OFs.Op,
HistFilaConj.Boletim,
HistFilaConj.Lote,
HistFilaConj.Conjugacao

FROM Trimbox.dbo.HistFilaConj
LEFT JOIN OFS ON Ofs.OP = HistFilaConj.OF1
WHERE
OFS.OP LIKE '%[0-9][0-9][0-9][0-9][0-9]-[0-9][0-9]/%'
AND OFS.OP LIKE '%[0-9][0-9][0-9][0-9]-[0-9]%'
AND OFS.OP LIKE '%[0-9][0-9]-[0-9]%'
AND OFS.OP LIKE '%[0-9][0-9][0-9]-[0-9]%'
AND Inicio IS NOT NULL
AND DataExpedicao IS NOT NULL
AND HistFilaConj.IdHist IN (SELECT DISTINCT HistFilaConj.IdHist FROM HistFilaConj)


GROUP BY HistFilaConj.Inicio,
OFs.OP,
OFs.DataExpedicao,
HistFilaConj.Conjugacao,
HistFilaConj.Lote,
HistFilaConj.Boletim,
HistFilaConj.IdHist

--HAVING HistFilaConj.IdHist > 1
HAVING HistFilaConj.Boletim > 1 AND HistFilaConj.Inicio > 1
ORDER BY HistFilaConj.IDHist DESC
Responder Citar

27/12/2013

Alex Lekao

Desculpe a intromissao, mas vc pode usar um subselect usando esse campo e no where do subselect vc usa algum campo que tenha relacao entre a tabela do select principal e o subselect, e se mesmo assim continuar o problema, vc pode fazer agrupamento deste campo na subselect.

Acho que pode ser uma alternativa para vc ter esse campo apenas uma unica vez.

Outra forma eh vc colocar na sub select um top 1 e order by campo desc, assim vc limita a um unico retorno na subselect, ai vc confere se os dados estao corretos.

Sugeri o order by com desc imaginando que vc queira o ultimo registro.

ESpero que ajude.

Abraco.

Alex - Lekao
Responder Citar

27/12/2013

Marcio Morando

Na verdade não quero somente o ultimo registro, quero todos os registros, mas somente um deles. O problema é que tem um pedido, e nesse pedido pode ser feito alterações. Quero que meu Select traga somente a último sempre, mas não estou conseguindo resolver. Consegue me passar um exemplo de como você soluciona esse problema?
Responder Citar

27/12/2013

Alex Lekao

Oi Marcio,

Desculpe mas nao entendi bem.

Vc quer esta usando alguma informacao de log de alteracao por exemplo?

Com o exemplo que sugeri da subselect eh possivel usando o order by desc trazer sempre o ultimo estado do historico.

Vou ver se consigo algum select aqui que faca algo parecido.

e posto em seguida.
Responder Citar

27/12/2013

Alex Lekao

Segue um codigo que tenho que pega ultimo registro.

Nele tem varias opcoes com subselect pegando ultimo registro e usando o top.

SELECT 
   CASE 
      WHEN I.CODLOJ = '001' THEN '001 - LAPA'
      WHEN I.CODLOJ = '002' THEN '002 - FREGUESIA'
      WHEN I.CODLOJ = '003' THEN '003 - BUTANTA'
      WHEN I.CODLOJ = '004' THEN '004 - JUNDIAI'
      WHEN I.CODLOJ = '005' THEN '005 - TATUAPE'
   ELSE 'SEM LOJA'
   END   AS LOJA,
   CASE WHEN S.CODDEP = '' OR S.CODDEP IS NULL THEN '' 
        ELSE S.CODDEP+' - '+DP.NOME 
   END AS DEPTO,
   I.CODSTK   AS CODIGO,
   S.CODFAB   AS NUMFAB,
   UPPER(SUBSTRING(S.MARCA,1,20)) AS FAB,
   S.ESTOQUE  AS ESTOQUE,
   S.ESTMIN   AS ESTMIN,
   S.ESTMAX   AS ESTMAX,
   S.CONSUMO  AS MDVDA,
   (S.ESTMAX - S.ESTOQUE) AS SUGESTMAX,
   S.PRCCUE   AS CUSTO,
   ISNULL(
          (SELECT 
              SUM(IC2.QTDADE)
           FROM  AS IC2
           LEFT JOIN  AS RC2 ON (RC2.SID = IC2.SID)
           WHERE RC2.TIPOREQ = 'PC'
              AND (IC2.CODSTK = I.CODSTK)
           GROUP BY IC2.CODSTK),0) AS PEDPEND,
   ISNULL(
          (SELECT 
              SUM(IC3.QTDADE)
           FROM ITEMCOM AS IC3
           LEFT JOIN REQCOM AS RC3 ON (RC3.SID = IC3.SID)
           WHERE RC3.TIPOREQ = 'PN'
              AND (IC3.CODSTK = I.CODSTK)
           GROUP BY IC3.CODSTK),0) AS PRENOTA,
   (SELECT 
       MAX(IC.DATEMI) 
    FROM  AS IC 
    LEFT JOIN  AS RC ON (RC.SID = IC.SID)
    WHERE IC.CODSTK = I.CODSTK
       AND RC.TIPOREQ = 'RC') AS DTULTCMP,
   (SELECT 
       TOP 1 RC2.CODCLI+' - '+F.NOME 
    FROM  AS RC2
    LEFT JOIN  AS IC2 ON (IC2.SID = RC2.SID)
    LEFT JOIN  AS F ON (F.CODCLI = RC2.CODCLI)
    WHERE RC2.TIPOREQ = 'RC'
       AND (IC2.CODSTK = I.CODSTK)
    ORDER BY RC2.DATEMI DESC) AS FORN
FROM  AS I
LEFT JOIN  AS S ON (S.CODSTK = I.CODSTK)
LEFT JOIN  AS R ON (R.SID = I.SID)
LEFT JOIN  AS DP ON (DP.CODDEP = S.CODDEP)
WHERE (1=1)
   AND S.CODDEP = [DADO8]
   AND S.CODDEP NOT IN [DADO9]
   AND R.TIPOREQ = 'VD'
   AND R.CODCPV NOT IN [DADO6]
   AND I.DATEMI >= [DADO1]
   AND I.DATEMI <= [DADO2]
   AND I.MARCA = [DADO4]
   AND R.CODVEN = [DADO3]
   AND (S.ESTOQUE <= 0 
   OR S.ESTOQUE <= S.ESTMIN)
   AND ((S.ESTMAX - S.ESTOQUE) <> 0)
GROUP BY I.CODLOJ,S.CODDEP,DP.NOME,I.CODSTK,S.CODFAB,S.MARCA,S.ESTOQUE,S.ESTMIN,S.ESTMAX,S.CONSUMO,S.PRCCUE
ORDER BY 1,2,3


Espero que ajude.

Abraco.

Alex - Lekao
Responder Citar