Ajuda com MAX() em Select SQL Server

13/11/2019

26

Olá,

Preciso que a query abaixo me retorne uma unica linha por pessoa , porem na funcao de agregacao o campo 'secao' possui linhas com dados diferentes, e eu preciso do MAX 'DATA_Mudanca' exatamente para pegar a ultima secao alterada. Porem não esta funcionando devido a secao ter informações diferentes.
Já tentei usar o MAX no subselect do select e do where e já tentei o having, mas todas estas opções dão erro pois ele não lê minha tabela criada PFHST em nenhum subselect.
Alguma sugestão?

SELECT
CHAPA,
NOME,
MES_COMP,
ANO_COMP,
PERIODO,
COD_EVENTO,
DESC_EVENTO,
SECAO,
MAX (DATA_MUDANCA) MUDANCA,
VALOR,
REFERENCIA,
DATA_PAGTO,
COD_SITUACAO,
DATA_ADMISSAO,
DATA_DEMISSAO
FROM
(SELECT
    PFUNC.CODCOLIGADA,
	PFUNC.CHAPA CHAPA, 
	PFUNC.NOME NOME, 
	PFFINANC.MESCOMP MES_COMP,
	PFFINANC.ANOCOMP ANO_COMP, 
	PFFINANC.NROPERIODO PERIODO,
	PEVENTO.CODIGO COD_EVENTO, 
	PEVENTO.DESCRICAO DESC_EVENTO, 
	PFHSTSEC.CODSECAO SECAO, 
	PFHSTSEC.DTMUDANCA DATA_MUDANCA,
	PFFINANC.VALOR VALOR, 
	PFFINANC.REF REFERENCIA,
	PFFINANC.DTPAGTO DATA_PAGTO, 
	PFUNC.CODSITUACAO COD_SITUACAO, 
	PFUNC.DATADEMISSAO  DATA_DEMISSAO, 
	PFUNC.DATAADMISSAO DATA_ADMISSAO
FROM PFFINANC 
LEFT OUTER JOIN GCOLIGADA ON (PFFINANC.CODCOLIGADA = GCOLIGADA.CODCOLIGADA)
LEFT OUTER JOIN PFUNC ON (((PFFINANC.CODCOLIGADA = PFUNC.CODCOLIGADA) AND (PFFINANC.CHAPA = PFUNC.CHAPA)))
LEFT OUTER JOIN PEVENTO ON ((PFFINANC.CODCOLIGADA = PEVENTO.CODCOLIGADA) AND (PFFINANC.CODEVENTO = PEVENTO.CODIGO) AND (PEVENTO.CODIGO = 0075) AND (PEVENTO.CODCOLIGADA = 22))
LEFT OUTER JOIN PFHSTSEC ON ((PFFINANC.CODCOLIGADA = PFHSTSEC.CODCOLIGADA) AND (PFFINANC.CHAPA = PFHSTSEC.CHAPA) AND (PFHSTSEC.CODCOLIGADA = 22))
WHERE PFFINANC.CODCOLIGADA = 22
  AND PFFINANC.ANOCOMP = 2018
  AND PFFINANC.MESCOMP = 04
  AND (('=' = '<>' AND PFFINANC.VALOR = 0) OR ('<>' = '<>' AND PFFINANC.VALOR <> 0))
  AND PFFINANC.NROPERIODO >= 2
  AND PFFINANC.CODEVENTO = 0075
  AND PFFINANC.DTPAGTO > PFHSTSEC.DTMUDANCA) AS PFHST
  WHERE CODCOLIGADA = 22
  AND ANO_COMP = 2018
  AND MES_COMP = 04
  AND (('=' = '<>' AND VALOR = 0) OR ('<>' = '<>' AND VALOR <> 0))
  AND PERIODO >= 2
  AND COD_EVENTO = 0075
  GROUP BY CHAPA,NOME,MES_COMP,ANO_COMP,PERIODO,COD_EVENTO,DESC_EVENTO,SECAO,VALOR,REFERENCIA,DATA_PAGTO,COD_SITUACAO,DATA_ADMISSAO,DATA_DEMISSAO
Responder

Post mais votado

14/11/2019

Olá, Juliana

Por favor, encaminhe os comandos CREATE das tabelas envolvidas nessa query e alguns INSERTs com dados reais para podermos simular seu select e vermos como resolver sua dúvida.

Obrigado.



Preciso que a query abaixo me retorne uma unica linha por pessoa , porem na funcao de agregacao o campo 'secao' possui linhas com dados diferentes, e eu preciso do MAX 'DATA_Mudanca' exatamente para pegar a ultima secao alterada. Porem não esta funcionando devido a secao ter informações diferentes.
Já tentei usar o MAX no subselect do select e do where e já tentei o having, mas todas estas opções dão erro pois ele não lê minha tabela criada PFHST em nenhum subselect.
Alguma sugestão?

SELECT
CHAPA,
NOME,
MES_COMP,
ANO_COMP,
PERIODO,
COD_EVENTO,
DESC_EVENTO,
SECAO,
MAX (DATA_MUDANCA) MUDANCA,
VALOR,
REFERENCIA,
DATA_PAGTO,
COD_SITUACAO,
DATA_ADMISSAO,
DATA_DEMISSAO
FROM
(SELECT
    PFUNC.CODCOLIGADA,
	PFUNC.CHAPA CHAPA, 
	PFUNC.NOME NOME, 
	PFFINANC.MESCOMP MES_COMP,
	PFFINANC.ANOCOMP ANO_COMP, 
	PFFINANC.NROPERIODO PERIODO,
	PEVENTO.CODIGO COD_EVENTO, 
	PEVENTO.DESCRICAO DESC_EVENTO, 
	PFHSTSEC.CODSECAO SECAO, 
	PFHSTSEC.DTMUDANCA DATA_MUDANCA,
	PFFINANC.VALOR VALOR, 
	PFFINANC.REF REFERENCIA,
	PFFINANC.DTPAGTO DATA_PAGTO, 
	PFUNC.CODSITUACAO COD_SITUACAO, 
	PFUNC.DATADEMISSAO  DATA_DEMISSAO, 
	PFUNC.DATAADMISSAO DATA_ADMISSAO
FROM PFFINANC 
LEFT OUTER JOIN GCOLIGADA ON (PFFINANC.CODCOLIGADA = GCOLIGADA.CODCOLIGADA)
LEFT OUTER JOIN PFUNC ON (((PFFINANC.CODCOLIGADA = PFUNC.CODCOLIGADA) AND (PFFINANC.CHAPA = PFUNC.CHAPA)))
LEFT OUTER JOIN PEVENTO ON ((PFFINANC.CODCOLIGADA = PEVENTO.CODCOLIGADA) AND (PFFINANC.CODEVENTO = PEVENTO.CODIGO) AND (PEVENTO.CODIGO = 0075) AND (PEVENTO.CODCOLIGADA = 22))
LEFT OUTER JOIN PFHSTSEC ON ((PFFINANC.CODCOLIGADA = PFHSTSEC.CODCOLIGADA) AND (PFFINANC.CHAPA = PFHSTSEC.CHAPA) AND (PFHSTSEC.CODCOLIGADA = 22))
WHERE PFFINANC.CODCOLIGADA = 22
  AND PFFINANC.ANOCOMP = 2018
  AND PFFINANC.MESCOMP = 04
  AND (('=' = '<>' AND PFFINANC.VALOR = 0) OR ('<>' = '<>' AND PFFINANC.VALOR <> 0))
  AND PFFINANC.NROPERIODO >= 2
  AND PFFINANC.CODEVENTO = 0075
  AND PFFINANC.DTPAGTO > PFHSTSEC.DTMUDANCA) AS PFHST
  WHERE CODCOLIGADA = 22
  AND ANO_COMP = 2018
  AND MES_COMP = 04
  AND (('=' = '<>' AND VALOR = 0) OR ('<>' = '<>' AND VALOR <> 0))
  AND PERIODO >= 2
  AND COD_EVENTO = 0075
  GROUP BY CHAPA,NOME,MES_COMP,ANO_COMP,PERIODO,COD_EVENTO,DESC_EVENTO,SECAO,VALOR,REFERENCIA,DATA_PAGTO,COD_SITUACAO,DATA_ADMISSAO,DATA_DEMISSAO



Olá... Boa Noite...

Não sei se entendi sua dúvida pois não sei qual estrutura de retorno estás usando , mas observei que sua necessidade é (para pegar a ultima secao alterada).
Retire tudo MAX no subselect, select e do where e o having se não estiver usando eles para outro critério

Tente usar

Order By DATA_Mudanca Desc

Dessa forma o retorno será sempre a última.
Responder

Mais Posts

14/11/2019

Valmir

Oi Juliana...seu select e bem extenso...mas criei 2 tabelas simples pessoa e secao e criei um select ,,,ve se ajuda...

CREATE TABLE [dbo].[pessoa](
[idpessoa] [int] NULL,
[nome] [varchar](50) NULL
) ON [PRIMARY]


CREATE TABLE [dbo].[secao](
[idsecao] [int] NULL,
[idpessoa] [int] NULL,
[descricaosecao] [varchar](50) NULL,
[data] [datetime] NULL
) ON [PRIMARY]


select * , (select max(data) from secao where idpessoa = pessoa.idpessoa) dataSecao
from pessoa
Responder

14/11/2019

Ricardo Ferrer

Olá, Juliana

Por favor, encaminhe os comandos CREATE das tabelas envolvidas nessa query e alguns INSERTs com dados reais para podermos simular seu select e vermos como resolver sua dúvida.

Obrigado.



Preciso que a query abaixo me retorne uma unica linha por pessoa , porem na funcao de agregacao o campo 'secao' possui linhas com dados diferentes, e eu preciso do MAX 'DATA_Mudanca' exatamente para pegar a ultima secao alterada. Porem não esta funcionando devido a secao ter informações diferentes.
Já tentei usar o MAX no subselect do select e do where e já tentei o having, mas todas estas opções dão erro pois ele não lê minha tabela criada PFHST em nenhum subselect.
Alguma sugestão?

SELECT
CHAPA,
NOME,
MES_COMP,
ANO_COMP,
PERIODO,
COD_EVENTO,
DESC_EVENTO,
SECAO,
MAX (DATA_MUDANCA) MUDANCA,
VALOR,
REFERENCIA,
DATA_PAGTO,
COD_SITUACAO,
DATA_ADMISSAO,
DATA_DEMISSAO
FROM
(SELECT
    PFUNC.CODCOLIGADA,
	PFUNC.CHAPA CHAPA, 
	PFUNC.NOME NOME, 
	PFFINANC.MESCOMP MES_COMP,
	PFFINANC.ANOCOMP ANO_COMP, 
	PFFINANC.NROPERIODO PERIODO,
	PEVENTO.CODIGO COD_EVENTO, 
	PEVENTO.DESCRICAO DESC_EVENTO, 
	PFHSTSEC.CODSECAO SECAO, 
	PFHSTSEC.DTMUDANCA DATA_MUDANCA,
	PFFINANC.VALOR VALOR, 
	PFFINANC.REF REFERENCIA,
	PFFINANC.DTPAGTO DATA_PAGTO, 
	PFUNC.CODSITUACAO COD_SITUACAO, 
	PFUNC.DATADEMISSAO  DATA_DEMISSAO, 
	PFUNC.DATAADMISSAO DATA_ADMISSAO
FROM PFFINANC 
LEFT OUTER JOIN GCOLIGADA ON (PFFINANC.CODCOLIGADA = GCOLIGADA.CODCOLIGADA)
LEFT OUTER JOIN PFUNC ON (((PFFINANC.CODCOLIGADA = PFUNC.CODCOLIGADA) AND (PFFINANC.CHAPA = PFUNC.CHAPA)))
LEFT OUTER JOIN PEVENTO ON ((PFFINANC.CODCOLIGADA = PEVENTO.CODCOLIGADA) AND (PFFINANC.CODEVENTO = PEVENTO.CODIGO) AND (PEVENTO.CODIGO = 0075) AND (PEVENTO.CODCOLIGADA = 22))
LEFT OUTER JOIN PFHSTSEC ON ((PFFINANC.CODCOLIGADA = PFHSTSEC.CODCOLIGADA) AND (PFFINANC.CHAPA = PFHSTSEC.CHAPA) AND (PFHSTSEC.CODCOLIGADA = 22))
WHERE PFFINANC.CODCOLIGADA = 22
  AND PFFINANC.ANOCOMP = 2018
  AND PFFINANC.MESCOMP = 04
  AND (('=' = '<>' AND PFFINANC.VALOR = 0) OR ('<>' = '<>' AND PFFINANC.VALOR <> 0))
  AND PFFINANC.NROPERIODO >= 2
  AND PFFINANC.CODEVENTO = 0075
  AND PFFINANC.DTPAGTO > PFHSTSEC.DTMUDANCA) AS PFHST
  WHERE CODCOLIGADA = 22
  AND ANO_COMP = 2018
  AND MES_COMP = 04
  AND (('=' = '<>' AND VALOR = 0) OR ('<>' = '<>' AND VALOR <> 0))
  AND PERIODO >= 2
  AND COD_EVENTO = 0075
  GROUP BY CHAPA,NOME,MES_COMP,ANO_COMP,PERIODO,COD_EVENTO,DESC_EVENTO,SECAO,VALOR,REFERENCIA,DATA_PAGTO,COD_SITUACAO,DATA_ADMISSAO,DATA_DEMISSAO
Responder
veja se isto te atende:
SELECT
	PFHST.*,
	MAX(PFHSTSEC.CODSECAO) SECAO
FROM
	(SELECT
		PFUNC.CODCOLIGADA,
		PFUNC.CHAPA,
		PFUNC.NOME,
		PFFINANC.MESCOMP MES_COMP,
		PFFINANC.ANOCOMP ANO_COMP,
		PFFINANC.NROPERIODO PERIODO,
		PEVENTO.CODIGO COD_EVENTO,
		PEVENTO.DESCRICAO DESC_EVENTO,
		MAX(PFHSTSEC.DTMUDANCA) DATA_MUDANCA, -- AQUI OBTÉM A MAIOR DATA
		PFFINANC.VALOR,
		PFFINANC.REF REFERENCIA,
		PFFINANC.DTPAGTO DATA_PAGTO,
		PFUNC.CODSITUACAO COD_SITUACAO,
		PFUNC.DATADEMISSAO  DATA_DEMISSAO,
		PFUNC.DATAADMISSAO DATA_ADMISSAO
	FROM
		PFFINANC
	LEFT JOIN GCOLIGADA
		ON (GCOLIGADA.CODCOLIGADA = PFFINANC.CODCOLIGADA)
	LEFT JOIN PFUNC
		ON (PFUNC.CODCOLIGADA = PFFINANC.CODCOLIGADA) AND (PFUNC.CHAPA = PFFINANC.CHAPA)
	LEFT JOIN PEVENTO ON
		(PEVENTO.CODCOLIGADA = PFFINANC.CODCOLIGADA) AND (PEVENTO.CODIGO = PFFINANC.CODEVENTO)
	LEFT JOIN PFHSTSEC ON
		(PFHSTSEC.CODCOLIGADA = PFFINANC.CODCOLIGADA) AND (PFHSTSEC.CHAPA = PFFINANC.CHAPA)
	WHERE
		PFFINANC.CODCOLIGADA = 22
		AND PFFINANC.ANOCOMP = 2018
		AND PFFINANC.MESCOMP = 04
		AND (('=' = '<>' AND PFFINANC.VALOR = 0) OR ('<>' = '<>' AND PFFINANC.VALOR <> 0))
		AND PFFINANC.NROPERIODO >= 2
		AND PFFINANC.CODEVENTO = 0075
		AND PFFINANC.DTPAGTO > PFHSTSEC.DTMUDANCA
	GROUP BY
		PFUNC.CODCOLIGADA,
		PFUNC.CHAPA,
		PFUNC.NOME,
		PFFINANC.MESCOMP,
		PFFINANC.ANOCOMP,
		PFFINANC.NROPERIODO,
		PEVENTO.CODIGO,
		PEVENTO.DESCRICAO,
		PFFINANC.VALOR,
		PFFINANC.REF,
		PFFINANC.DTPAGTO,
		PFUNC.CODSITUACAO,
		PFUNC.DATADEMISSAO,
		PFUNC.DATAADMISSAO
	) AS PFHST
LEFT JOIN PFHSTSEC ON
	(PFHSTSEC.CODCOLIGADA = PFHST.CODCOLIGADA) AND (PFHSTSEC.CHAPA = PFHST.CHAPA)
	AND (PFHSTSEC.DTMUDANCA = PFHST.DATA_MUDANCA) -- AQUI VINCULA A SECAO DE MAIOR DATA, AFIM DE OBTER SEU CÓDIGO
Responder

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários. Para saber mais sobre o uso de cookies,
consulte nossa política de privacidade. Ao continuar navegando em nosso site, você concorda com a nossa política.

Aceitar