PROBLEMA COM INSTRUCAO SQL

LUIS.HERRERA 27/09/2012 11:38:17
#410659
Bom dia.
Estou montando uma consulta no VB6 para extrais alguns dados do Access, onde tenho de pegar 3 campos de uma tabela:

Estrutura: tabAprovacaoDoc
cmpIDdoc
cmpNomeAprovador
cmpDataAprovacao

A instrução está assim:
SELECT tabAprovacaoDoc.cmpIDdoc, tabAprovacaoDoc.cmpNomeAprovador AS Aprovador, Max(tabAprovacaoDoc.cmpDataAprovacao) AS DTAprovacao
FROM tabAprovacaoDoc
GROUP BY tabAprovacaoDoc.cmpIDdoc, tabAprovacaoDoc.cmpNomeAprovador
ORDER BY tabAprovacaoDoc.cmpIDdoc, Max(tabAprovacaoDoc.cmpDataAprovacao);

O problema é que esta instrução trás todos os registros que eu quero, mas caso o aprovador de algum deles seja diferente para o mesmo campo cmpNomeAprovador, ele repete o registro, com a maior data de cada Aprovador.

Na realidade o que eu preciso é trazer um único registro de cada cmpIDDoc com a maior (mais recente) data de aprovação, independente de quem fez a aprovação. Assim posso ter um documento com dezenas de aprovações, mas quero apenas a última, com seus dados (Doc, nome aprovador e data).

Como posso resolver isso?

Nota: a linha GROUP BY tabAprovacaoDoc.cmpIDdoc, tabAprovacaoDoc.cmpNomeAprovador foi o próprio editor do access que criou, ao incluir o parâmetro totais e usar o Max. Acho que essa linha que está gerando o problema, já que há dados diferentes no campo cmpNomeAprovador para uma mesma cmpIDDoc, porém se eu tirar esse campo do GROUP By, a consulta não funcona.
FILMAN 27/09/2012 21:13:44
#410724
Isso vai te ajudar!

SELECT DISTINCT 
AD.cmpIDdoc, NOME, DATA
FROM
tabAprovacaoDoc AD,
(
SELECT
AD.cmpNomeAprovador AS NOME, Max(AD.cmpDataAprovacao) AS DATA
FROM
tabAprovacaoDoc AD
GROUP BY AD.cmpNomeAprovador
)
WHERE
AD.cmpNomeAprovador = NOME AND AD.cmpDataAprovacao = DATA
GROUP BY AD.cmpIDdoc, NOME, DATA
LUIS.HERRERA 28/09/2012 10:32:24
#410758
Filman bom dia.
Obrigado pela ajuda, mas acho que esta instrução não funciona no MS Access. Ao tentar rodar, seu erro na instrução SQL e seleciona o segundo SELECT como se fosse ele o problema.

FILMAN 28/09/2012 15:29:46
#410789
Cara eu fiz isso dentro do access e deu certo vou mandar pra o banco assim que eu chegar em casa!
LLAIA 28/09/2012 15:43:58
#410792
Bom, eu tentaria mudar duas coisas aí nessa query do FILMAN pra parar com o erro:

1 - A subquery usa um alias igual a query externa (AD). talvez tá dando problema aí.
2 - Na subquery temos um alias [txt-color=#e80000]DATA[/txt-color] para o campo agregado Max. A palavra DATA no Jet Database, até onde eu lembro, é uma palavra reservada. Não sei se nas versões mais recentes isso não gere problemas.

são apenas chutes senhores.
FILMAN 28/09/2012 22:41:02
#410817
Segue o banco conforme eu prometi

dentro do banco esta uma consulta com o SQL que postei acima
LUIS.HERRERA 04/10/2012 07:43:11
#411212
Fiman boa dia.
Desculpe só responder agora, mas início de mês tenho toda contabilidade para fazer.

Vi seu código, testei e funcionou, mas ao usar os dados e estrutura real da minha tabela, não trás as informações corretas.
Segue anexo seu banco, com duas novas tabelas:
* a tabAprovacaoDoc agora é idêntica a minha tabela, estrutura e dados
* a DadosCorretosParaExibir, tem os dados que a consulta deverá trazer, veja que ao rodar sua consulta os dados são outros.

Nota: Renomeie sua tabela inicial tabAprovacaoDoc_SeuAnterior

1) Não entendi o que são esses caracteres [%$##@_Alias] que usou?

Grato antecipadamente por sua ajuda.

FILMAN 04/10/2012 20:49:25
#411304
Cara tenta assim que vai dar certo

Dim SQL As String

[ô]Isso aqui já funciona!!!
SQL = [Ô]SELECT [Ô]
SQL = SQL & [Ô] AUX.DOC, AD.cmpIDENTIFICADOR AS IDENT, AD.cmpIDAprovador, AUX.NOME, AUX.uDATA, Max(AD.cmpHoraAprovacao) AS uHORA [Ô]
SQL = SQL & [Ô] FROM tabAprovacaoDoc AS AD, [Ô]
SQL = SQL & [Ô] ([Ô]
SQL = SQL & [Ô] SELECT [Ô]
SQL = SQL & [Ô] iAD.cmpIDdoc AS DOC, iAD.cmpNomeAprovador AS NOME, Max(iAD.cmpDataAprovacao) AS uDATA [Ô]
SQL = SQL & [Ô] FROM tabAprovacaoDoc AS iAD [Ô]
SQL = SQL & [Ô] GROUP BY iAD.cmpIDdoc, iAD.cmpNomeAprovador [Ô]
SQL = SQL & [Ô] ) AS AUX [Ô]
SQL = SQL & [Ô] WHERE [Ô]
SQL = SQL & [Ô] AD.cmpNomeAprovador=AUX.NOME AND AD.cmpDataAprovacao=AUX.uDATA AND AD.cmpIDdoc=AUX.DOC [Ô]
SQL = SQL & [Ô] GROUP BY AUX.DOC, AD.cmpIDENTIFICADOR, AD.cmpIDAprovador, AUX.NOME, AUX.uDATA [Ô]



[ô]Mas caso queira retornar o ID da tabela também faça assim
SQL = [Ô]SELECT AP.cmpID AS ID, J.DOC, J.IDENT, J.cmpIDAprovador, J.NOME, J.uDATA, J.uHORA [Ô]
SQL = SQL & [Ô]FROM tabAprovacaoDoc AS AP, [Ô]
SQL = SQL & [Ô]([Ô]
SQL = SQL & [Ô] SELECT [Ô]
SQL = SQL & [Ô] AUX.DOC, AD.cmpIDENTIFICADOR AS IDENT, AD.cmpIDAprovador, AUX.NOME, AUX.uDATA, Max(AD.cmpHoraAprovacao) AS uHORA [Ô]
SQL = SQL & [Ô] FROM tabAprovacaoDoc AS AD, [Ô]
SQL = SQL & [Ô] ([Ô]
SQL = SQL & [Ô] SELECT [Ô]
SQL = SQL & [Ô] iAD.cmpIDdoc AS DOC, iAD.cmpNomeAprovador AS NOME, Max(iAD.cmpDataAprovacao) AS uDATA [Ô]
SQL = SQL & [Ô] FROM tabAprovacaoDoc AS iAD [Ô]
SQL = SQL & [Ô] GROUP BY iAD.cmpIDdoc, iAD.cmpNomeAprovador [Ô]
SQL = SQL & [Ô] ) AS AUX [Ô]
SQL = SQL & [Ô] WHERE [Ô]
SQL = SQL & [Ô] AD.cmpNomeAprovador=AUX.NOME AND AD.cmpDataAprovacao=AUX.uDATA AND AD.cmpIDdoc=AUX.DOC [Ô]
SQL = SQL & [Ô] GROUP BY AUX.DOC, AD.cmpIDENTIFICADOR, AD.cmpIDAprovador, AUX.NOME, AUX.uDATA [Ô]
SQL = SQL & [Ô]) AS J [Ô]
SQL = SQL & [Ô]WHERE [Ô]
SQL = SQL & [Ô] AP.cmpNomeAprovador = J.NOME [Ô]
SQL = SQL & [Ô] AND AP.cmpDataAprovacao = J.uDATA [Ô]
SQL = SQL & [Ô] AND AP.cmpIDdoc = J.DOC [Ô]
SQL = SQL & [Ô] AND AP.cmpIDENTIFICADOR = J.IDENT[Ô]
SQL = SQL & [Ô] AND AP.cmpHoraAprovacao = J.uHORA[Ô]
SQL = SQL & [Ô] ORDER BY J.NOME[Ô]




Vlw
LUIS.HERRERA 05/10/2012 07:51:46
#411317
Filman muito obrigado pela atenção, porém ainda não está trazendo os dados corretos.
Incluí ambas as consulta no banco e cada uma trás dados diferentes, proém nenhum os que são necessários.

Veja que na tabela DadosCorretosParaExibir, eu incluí somente os dados que sevem ser carregados pela consulta, como forma de conferir se funciona.

O que ocorre na consulta 2 é que trás dados repetidos em alguns campos, como identificador e na consulta 2 além da repetição, os registros não estão ordenados corretamente pelo Identificador.

Explicando a necessidade:
- tenho diversos registros de Identificadores
- cada um tem um aprovador, uma data de realização e um horário

O que preciso é pegar todos os identificadores da tabela, porém somente o último cadastrado de cada identificador, ou seja, se tiver 50 identificadores iguais, pego o que tiver data mais recente e se tiver 2 identificadores incluídos nesta mesma data, prevalece o que tiver o horário mais recente. Porém é necessário trazer todos os campos desta tabela para exibição no relatório.

Nota: O que está causando o problema, é que um identificador pode ter nomes de aprovadores diferentes, sendo assim a consulta não deve diferenciar o nome do aprovador, mas sim a aprovação mais recente para este identificador que não pode ser repetido na consulta, tem que vir apenas um único registro para cada identificador e o mais recente.

Para que a consulta funcione é preciso que os dados carregados sejam idênticos aos contidos na tabela DadosCorretosParaExibir pois já estão filtrados para comparação..
FFCOUTO 05/10/2012 09:45:41
#411326
Resposta escolhida
Luis, veja se isso resolve o problema:


SELECT cmpID, cmpIDdoc, cmpIDAprovador, cmpNomeAprovador, cmpDataAprovacao, cmpHoraAprovacao
FROM tabAprovacaoDoc AS temp1
WHERE cmpID = (SELECT TOP 1 cmpID FROM tabAprovacaoDoc WHERE (cmpIDDoc = temp1.cmpIDdoc) ORDER BY cmpDataAprovacao DESC, cmpHoraAprovacao DESC)
ORDER BY cmpIDdoc


LUIS.HERRERA 05/10/2012 11:15:16
#411349
FFCouto Perfeito, só inclui + o cmapo Identicador e ordenei por ele e funcionou certinho, muito obrigado mesmo.

Você tem algum material sobre SQL avançado, como fazer consultas dessa forma para extrair dados em condições específicas, pois uso o assistente do MSAccess para isso, mas ele é muito limitado.
Será que existe algum aplicativo que auxilie a criar SQL?

Obrigado novamente.
Luis
Página 1 de 2 [12 registro(s)]
Tópico encerrado , respostas não são mais permitidas