Consulta no MYSQL

Bom dia Pessoal,

Estou com certa dificuldade em relacionar duas tabelas no mysql.

O que acontece é o seguinte:

Tabela integracao_veiculos ( 257 registros )

  • idVeiculo
  • placa
  • motorista

Tabela integracao_eventos ( 374329 registros, a cada 30 seg recebo em media + 100 registros )

  • idVeiculo
  • idMensagem
  • latitude
  • longitude

Querry que estou utilizando para mostrar os registros,

[code]SELECT * FROM integracao_veiculos 
	INNER JOIN integracao_eventos ON (integracao_veiculos.idVeiculo = integracao_eventos.idVeiculo) ORDER BY integracao_veiculos.placa 

[/code]

Mas no caso eu preciso mostrar apenas o ultimo registro de cada veiculo ( hoje seriam 257 veiculos e nao os 374329 ).

Ja tentei utilizar o Group By mas mesmo assim demora muito ( ele continua percorrendo a tabela toda dos eventos antes de retornar os dados ).

De que forma eu posso fazer isso ?

Desde ja muito obrigado.

Abraco

Algo assim?

SELECT * FROM integracao_veiculos v  
            INNER JOIN integracao_eventos e ON v.idVeiculo = e.idVeiculo) 
 WHERE e.idMensagem = (SELECT max(e2.idMensagem) FROM integracao_eventos e2 WHERE e.idVeiculo = e2.idVeiculo)
 ORDER BY integracao_veiculos.placa   

Eu acho que o seu problema está na modelagem do banco de dados. Como você sabe qual row da tabela integracao_eventos é o último registro referente a um veículo? Você deveria ter um campo tipo ind_vigente_integracao (boolean ou varchar para ´S´/´N’), onde somente a integração seria TRUE (ou ´S´) ou então um campo de data_disponibilizacao na tabela integracao_eventos. Assim , você poderia complementar a sua query da seguinte forma:

SELECT * FROM integracao_veiculos 
		INNER JOIN integracao_eventos ON (integracao_veiculos.idVeiculo = integracao_eventos.idVeiculo) 
WHERE IND_VIGENTE_INTEGRACAO = 'S'
ORDER BY integracao_veiculos.placa

Ou, para o caso de data:

SELECT * FROM integracao_veiculos 
		INNER JOIN integracao_eventos ON (integracao_veiculos.idVeiculo = integracao_eventos.idVeiculo) 
WHERE DATA_DISPONIBILIZACAO = (SELECT MAX(DATA_DISPONIBILIZACAO) FROM integracao_eventos
                                                        WHERE  integracao_eventos.idVeiculo = integracao_veiculos.idVeiculo)
ORDER BY integracao_veiculos.placa

[quote=pmlm]Algo assim?

SELECT * FROM integracao_veiculos v INNER JOIN integracao_eventos e ON v.idVeiculo = e.idVeiculo) WHERE e.idMensagem = (SELECT max(e2.idMensagem) FROM integracao_eventos e2 WHERE e.idVeiculo = e2.idVeiculo) ORDER BY integracao_veiculos.placa [/quote]

Valeu pela ajuda pmlm, mas nao rolou :S

[quote=alex1975]Eu acho que o seu problema está na modelagem do banco de dados. Como você sabe qual row da tabela integracao_eventos é o último registro referente a um veículo? Você deveria ter um campo tipo ind_vigente_integracao (boolean ou varchar para ´S´/´N’), onde somente a integração seria TRUE (ou ´S´) ou então um campo de data_disponibilizacao na tabela integracao_eventos. Assim , você poderia complementar a sua query da seguinte forma:

SELECT * FROM integracao_veiculos 
		INNER JOIN integracao_eventos ON (integracao_veiculos.idVeiculo = integracao_eventos.idVeiculo) 
WHERE IND_VIGENTE_INTEGRACAO = 'S'
ORDER BY integracao_veiculos.placa

Ou, para o caso de data:

SELECT * FROM integracao_veiculos 
		INNER JOIN integracao_eventos ON (integracao_veiculos.idVeiculo = integracao_eventos.idVeiculo) 
WHERE DATA_DISPONIBILIZACAO = (SELECT MAX(DATA_DISPONIBILIZACAO) FROM integracao_eventos
                                                        WHERE  integracao_eventos.idVeiculo = integracao_veiculos.idVeiculo)
ORDER BY integracao_veiculos.placa

[/quote]

Alex1975,

Cara eu tenho um campo data na tabela eventos. ( tipo datetime )

No caso a querry ficaria assim certo ?

SELECT * FROM integracao_veiculos INNER JOIN integracao_eventos ON (integracao_veiculos.idVeiculo = integracao_eventos.idVeiculo) WHERE integracao_eventos.data = (SELECT MAX(integracao_eventos.data) FROM integracao_eventos WHERE integracao_eventos.idVeiculo = integracao_veiculos.idVeiculo) ORDER BY integracao_veiculos.placa

Deu algum erro?

[quote=alex1975]

SELECT * FROM integracao_veiculos INNER JOIN integracao_eventos ON (integracao_veiculos.idVeiculo = integracao_eventos.idVeiculo) WHERE integracao_eventos.data = (SELECT MAX(integracao_eventos.data) FROM integracao_eventos WHERE integracao_eventos.idVeiculo = integracao_veiculos.idVeiculo) ORDER BY integracao_veiculos.placa[/quote]
Sim. Se reparares essa query é igual à minha. Eu pressupos que o ultimo registo seria o que tivesse idMensagem maior. Aqui o último registo é o que tem a data maior.

[quote=pmlm][quote=leandrosu]
Valeu pela ajuda pmlm, mas nao rolou :S
[/quote]
Deu algum erro?

[quote=alex1975]

SELECT * FROM integracao_veiculos INNER JOIN integracao_eventos ON (integracao_veiculos.idVeiculo = integracao_eventos.idVeiculo) WHERE integracao_eventos.data = (SELECT MAX(integracao_eventos.data) FROM integracao_eventos WHERE integracao_eventos.idVeiculo = integracao_veiculos.idVeiculo) ORDER BY integracao_veiculos.placa[/quote]
Sim. Se reparares essa query é igual à minha. Eu pressupos que o ultimo registo seria o que tivesse idMensagem maior. Aqui o último registo é o que tem a data maior.[/quote]

Entao,

Executei a query pelo mysql-front mesmo e ele nao retorna nem erro e nenhum registro.

Segue um screen dos ultimos registros do banco

Experimenta usar a seguinte query:

SELECT * FROM integracao_veiculos v    
            INNER JOIN integracao_eventos e ON v.idVeiculo = e.idVeiculo)   
WHERE e.idMensagem = (SELECT max(e2.id) FROM integracao_eventos e2 WHERE e.idVeiculo = e2.idVeiculo)  
ORDER BY integracao_veiculos.placa   

É quase igual a query do pmlm, mas usa o campo id do integracao_eventos, que é a pk. Talvez a data não tenha rolado devido ao formato ddmmyyy hh21mmss. No Oracle eu costumo truncar estas datas, mas vai vir várias. E se você utilizar o campo idMensagem também vai vir várias, pois se repete. Tomara que agora funcione.

[quote=alex1975]Experimenta usar a seguinte query:
[/quote]
Uma pequena correção:

SELECT * FROM integracao_veiculos v    
            INNER JOIN integracao_eventos e ON v.idVeiculo = e.idVeiculo)   
WHERE e.id= (SELECT max(e2.id) FROM integracao_eventos e2 WHERE e.idVeiculo = e2.idVeiculo)  
ORDER BY integracao_veiculos.placa   

[quote=alex1975]Experimenta usar a seguinte query:

SELECT * FROM integracao_veiculos v    
            INNER JOIN integracao_eventos e ON v.idVeiculo = e.idVeiculo)   
WHERE e.idMensagem = (SELECT max(e2.id) FROM integracao_eventos e2 WHERE e.idVeiculo = e2.idVeiculo)  
ORDER BY integracao_veiculos.placa   

É quase igual a query do pmlm, mas usa o campo id do integracao_eventos, que é a pk. Talvez a data não tenha rolado devido ao formato ddmmyyy hh21mmss. No Oracle eu costumo truncar estas datas, mas vai vir várias. E se você utilizar o campo idMensagem também vai vir várias, pois se repete. Tomara que agora funcione.[/quote]

Valeu Alex, mas continua na mesma ele nao retorna nada :S
O que sera que pode ser ?

[quote=pmlm][quote=alex1975]Experimenta usar a seguinte query:
[/quote]
Uma pequena correção:

SELECT * FROM integracao_veiculos v    
            INNER JOIN integracao_eventos e ON v.idVeiculo = e.idVeiculo)   
WHERE e.id= (SELECT max(e2.id) FROM integracao_eventos e2 WHERE e.idVeiculo = e2.idVeiculo)  
ORDER BY integracao_veiculos.placa   

[/quote]

pmlm, cara tb nao retorna nada.

Ja to ficando meio maluco aqui. Ou demora mais de 1 min pra retornar tudo ( ai vem coisa que nem precisa ) ou nao retorna nada =/

Deixei essa querry rodando:

Demorou 02:23 min pra retornar 195 registros.

De que forma eu poderia otimizar essa consulta ?

Para mim o melhor seria o campo de ind_vigente_integracao que eu mencionei anteriormente. O select max percorre todo o banco e faz comparação sobre qual é o maior. Se para a tabela integracao_eventos somente o último registro para determinado veículo tivesse status = ´S´ (ou true), a execução seria mais rápida.