Últimos registros em select sem usar limit
Boa noite amigos! Estou precisando de uma ajuda.
Tenho 4 tabelas: usuários, problemas, evolução, atendimento.
A tabela evolução está relacionada com a de problemas e de atendimento, e a de problemas com a de usuários.
Estou trabalhando com delphi e o que preciso é que seja mostrado na dbgrid o ultimo registro de evolução (que teoricamente seria o último atendimento feito para aquele usuário) de cada um dos problemas do usuário.
Ex.:
Para o usuário A um grid com os problemas dele
Problema 1 - última evolução
Problema 2 - última evolução
Para o usuário B um outro grid com os problemas dele.
Não posso usar limit pois um usuário poder ter n problemas.
Até tinha feito funcionar o esquema, fazia um filtro pelo código do usuário na tabela de atendimento, dava um last, pegava o ID desse atendimento e fazia um novo filtro na tabela de evolução. Ele traz os resultados certinho.
Só que dessa forma, se eu cadastrar um novo problema, ele nunca irá aparecer na grid pra ver a evolução - esse problema nao necessariamente precisa ser cadastrado em um atendimento, entao o filtro iria falhar aqui.
Da mesma forma, se eu cadastro um problema durante o atendimento, ele nao aparece na grade - não tem evolução, além de que a grade está mostrando os registros do último atendimento.
Por fim, quando faço uma alteração na evolução do problema, ela continua na grid, e eu gostaria que sumisse dali pra nao confundir o operador.
Não sei se ficou claro... Já pensei várias formas de contornar isso e ainda não achei solução.
Tenho 4 tabelas: usuários, problemas, evolução, atendimento.
A tabela evolução está relacionada com a de problemas e de atendimento, e a de problemas com a de usuários.
Estou trabalhando com delphi e o que preciso é que seja mostrado na dbgrid o ultimo registro de evolução (que teoricamente seria o último atendimento feito para aquele usuário) de cada um dos problemas do usuário.
Ex.:
Para o usuário A um grid com os problemas dele
Problema 1 - última evolução
Problema 2 - última evolução
Para o usuário B um outro grid com os problemas dele.
Não posso usar limit pois um usuário poder ter n problemas.
Até tinha feito funcionar o esquema, fazia um filtro pelo código do usuário na tabela de atendimento, dava um last, pegava o ID desse atendimento e fazia um novo filtro na tabela de evolução. Ele traz os resultados certinho.
Só que dessa forma, se eu cadastrar um novo problema, ele nunca irá aparecer na grid pra ver a evolução - esse problema nao necessariamente precisa ser cadastrado em um atendimento, entao o filtro iria falhar aqui.
Da mesma forma, se eu cadastro um problema durante o atendimento, ele nao aparece na grade - não tem evolução, além de que a grade está mostrando os registros do último atendimento.
Por fim, quando faço uma alteração na evolução do problema, ela continua na grid, e eu gostaria que sumisse dali pra nao confundir o operador.
Não sei se ficou claro... Já pensei várias formas de contornar isso e ainda não achei solução.
Franthesco Guarda
Curtidas 0
Respostas
Jerson Boer
26/01/2018
Olá Francesco, veja se ajuda na montagem da sua query:
Eu uso uma ideia similar em um sistema meu que trás Proposta + Última de N interações existentes naquela proposta.
A ideia neste caso é o seguinte:
1) Uma tabela que tem os seus usuários
2) Uma tabela com os problemas deste usuário
3) Uma tabela com N evoluções de cada um dos problemas
Neste código você vai trazer os usuários e todos os problemas dele. Na query que montei chamando de BuscaUltProblema ele pega, dentre as evoluções, qual foi a última criada, depois, fora dessa query, faço um relacionamento deste código com a tabela de evolução, trazendo assim:
Usuário A
Problema 1 - Evolução X
Problema 2 - Evolução Y
Usuário B
Problema 1 - Evolução Z
Veja se consegue entender a ideia e qualquer coisa retorne como ficou seu código para verificação.
Eu uso uma ideia similar em um sistema meu que trás Proposta + Última de N interações existentes naquela proposta.
SELECT Usuarios.Usuario, Problema.DescricaoProblema, Evolucao.DescricaoEvolucao FROM Usuarios INNER JOIN Problema ON Problema.codigousuario = Usuarios.CodigoUsuario LEFT JOIN (SELECT Problema.CodigoProblema, MAX(Evolucao.CodigoEvolucao) AS CodigoUltimaEvolucao FROM Evolucao GROUP BY Problema.CodigoProblema) AS BuscaUltProblema ON BuscaUltProblema.CodigoProblema = problema.CodigoProblema LEFT JOIN Evolucao ON BuscaUltProblema.CodigoUltimaEvolucao = Evolucao.CodigoEvolucao
A ideia neste caso é o seguinte:
1) Uma tabela que tem os seus usuários
2) Uma tabela com os problemas deste usuário
3) Uma tabela com N evoluções de cada um dos problemas
Neste código você vai trazer os usuários e todos os problemas dele. Na query que montei chamando de BuscaUltProblema ele pega, dentre as evoluções, qual foi a última criada, depois, fora dessa query, faço um relacionamento deste código com a tabela de evolução, trazendo assim:
Usuário A
Problema 1 - Evolução X
Problema 2 - Evolução Y
Usuário B
Problema 1 - Evolução Z
Veja se consegue entender a ideia e qualquer coisa retorne como ficou seu código para verificação.
GOSTEI 0
Franthesco Guarda
26/01/2018
Bom dia Jerson! Obrigado por sua resposta. Montei a query conforme a que você passou. Ele está mostrando agora os problemas que ainda não tem nenhuma evolução cadastrada, como eu queria. Porém, ele pega a última evolução e coloca ela em todos os problemas. Fiz um teste assim:
Usuário 1
Problema 1.1 - Evolução A
Problema 1.2 - Evolução B
Problema 1.1 - Evolução C
Usuário 2
Problema 2.1 - Evolução D
Executando a query, ele coloca como evolução para os problemas 1.2, 1.1, 2.1 todas como D. Segue o código que estou usando:
Tentei algumas alterações como mudar campos, relacionamentos, mas aí ele passava a retornar null em todas as evoluções. Se puderes me dar mais uma ajuda, agradeço!
Usuário 1
Problema 1.1 - Evolução A
Problema 1.2 - Evolução B
Problema 1.1 - Evolução C
Usuário 2
Problema 2.1 - Evolução D
Executando a query, ele coloca como evolução para os problemas 1.2, 1.1, 2.1 todas como D. Segue o código que estou usando:
SELECT usu_cad.c1, usu_pato.c4, atend_evol_pato.c6 FROM usu_cad INNER JOIN usu_pato ON usu_pato.c2 = usu_cad.c1 LEFT JOIN (SELECT usu_pato.c1, MAX(atend_evol_pato.c1) AS CodigoUltimaEvolucao FROM atend_evol_pato, usu_pato GROUP BY usu_pato.c1) AS BuscaUltProblema ON BuscaUltProblema.c1 = usu_pato.c1 LEFT JOIN atend_evol_pato ON BuscaUltProblema.CodigoUltimaEvolucao = atend_evol_pato.c1
Tentei algumas alterações como mudar campos, relacionamentos, mas aí ele passava a retornar null em todas as evoluções. Se puderes me dar mais uma ajuda, agradeço!
GOSTEI 0
Jerson Boer
26/01/2018
Bom dia Franthesco.
Só pra eu tentar entender a sua estrutura, você tem:
> Paciente
> Patologia
> Evolução
Então imagino que a query que busca o último registro tem que ter relacionamento somente com a patologia e não com a tabela de paciente, algo mais ou menos assim:
Verifique e retorne caso ainda não apresente o resultado esperado.
Só pra eu tentar entender a sua estrutura, você tem:
> Paciente
> Patologia
> Evolução
Então imagino que a query que busca o último registro tem que ter relacionamento somente com a patologia e não com a tabela de paciente, algo mais ou menos assim:
SELECT usu_cad.c1, usu_pato.c4, atend_evol_pato.c6 FROM usu_cad INNER JOIN usu_pato ON usu_pato.c2 = usu_cad.c1 LEFT JOIN (SELECT atend_evol_pato.CodigoChaveComPatologia, MAX(atend_evol_pato.c1) AS CodigoUltimaEvolucao FROM atend_evol_pato GROUP BY atend_evol_pato.CodigoChaveComPatologia) AS BuscaUltProblema ON BuscaUltProblema.CodigoChaveComPatologia = usu_pato.CodigoChaveComPatologia LEFT JOIN atend_evol_pato ON BuscaUltProblema.CodigoUltimaEvolucao = atend_evol_pato.c1
Verifique e retorne caso ainda não apresente o resultado esperado.
GOSTEI 0
Franthesco Guarda
26/01/2018
Jerson, muito obrigado! Funcionou perfeitamente! Inclusive, estudando o código, consegui juntar ainda outras informações (ex. o nome da patologia, que estava codificado).
Consegui ainda usar para outras partes do programa, tudo funcionando certinho!
Mais uma vez, muito obrigado pela ajuda!
Consegui ainda usar para outras partes do programa, tudo funcionando certinho!
Mais uma vez, muito obrigado pela ajuda!
GOSTEI 0
Jerson Boer
26/01/2018
Que bom que deu certo o código.. Precisando, só postar novamente... Abraços..
GOSTEI 0