PROBLEMA COM INSTRUCAO SQL
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.
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.
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
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.
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.
Cara eu fiz isso dentro do access e deu certo vou mandar pra o banco assim que eu chegar em casa!
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.
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.
Segue o banco conforme eu prometi
dentro do banco esta uma consulta com o SQL que postei acima
dentro do banco esta uma consulta com o SQL que postei acima
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.
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.
Cara tenta assim que vai dar certo
Vlw
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
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..
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..
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
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
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
Tópico encerrado , respostas não são mais permitidas