Eu tenho um cliente de tabela que armazena um customer_id, email e referência. Existe uma tabela adicional customer_data que armazena um registro histórico das alterações feitas ao cliente, ou seja, quando há uma alteração feita uma nova linha é inserida.
Para exibir as informações do cliente em uma tabela, as duas tabelas precisam ser unidas; no entanto, apenas a linha mais recente de customer_data deve ser unida à tabela do cliente.
Fica um pouco mais complicado porque a consulta é paginada e, portanto, tem um limite e um deslocamento.
Como posso fazer isso com o MySQL? Acho que estou querendo colocar um DISTINTO em algum lugar ...
A consulta no minuto é assim-
SELECT *, CONCAT(title,' ',forename,' ',surname) AS name
FROM customer c
INNER JOIN customer_data d on c.customer_id=d.customer_id
WHERE name LIKE '%Smith%' LIMIT 10, 20
Além disso, estou certo em pensar que posso usar CONCAT com LIKE dessa forma?
(Compreendo que INNER JOIN pode ser o tipo errado de JOIN para usar. Na verdade, não tenho ideia de qual é a diferença entre os diferentes JOINs. Vou analisar isso agora!)
Respostas:
Você pode tentar o seguinte:
Observe que a
JOIN
é apenas um sinônimo deINNER JOIN
.Caso de teste:
Resultado (consulta sem
LIMIT
eWHERE
):fonte
Se você estiver trabalhando com consultas pesadas, é melhor mover a solicitação para a linha mais recente na cláusula where. É muito mais rápido e parece mais limpo.
fonte
sql_no_cache set
), ao passo que fazer a pesquisa na junção levou vários segundos para ser concluída. Ainda perplexo, mas quero dizer que você não pode contestar resultados como esse.Presumindo que a coluna de incremento automático em
customer_data
seja nomeadaId
, você pode fazer:fonte
Para quem precisa trabalhar com uma versão mais antiga do MySQL (pré-5.0 ish), você não pode fazer subconsultas para este tipo de consulta. Aqui está a solução que consegui fazer e parecia funcionar muito bem.
Essencialmente, isso é encontrar o id máximo de sua tabela de dados unindo-o ao cliente e, em seguida, unindo a tabela de dados ao id máximo encontrado. A razão para isso é porque selecionar o máximo de um grupo não garante que o resto dos dados correspondam ao id, a menos que você os junte de volta a si mesmos.
Eu não testei isso em versões mais recentes do MySQL, mas funciona em 4.0.30.
fonte
EXPLAIN
indica que isso usa uma tabela e um tipo de arquivo temporários. AdicionarORDER BY NULL
no final elimina o tipo de arquivo.SELECT *, MAX(firstData.id), MAX(secondData.id) [...]
. Logicamente, ao mudar para,SELECT main.*, firstData2.*, secondData2.*, MAX(firstData.id), MAX(secondData.id), [...]
fui capaz de torná-lo significativamente mais rápido. Isso permite que as primeiras junções leiam apenas do índice, em vez de também ter que ler todos os dados do índice primário. Agora, a solução bonita leva apenas 1,9 vezes mais do que a solução baseada em subconsulta.Sei que essa pergunta é antiga, mas tem recebido muita atenção ao longo dos anos e acho que está faltando um conceito que pode ajudar alguém em um caso semelhante. Estou adicionando aqui para fins de integridade.
Se você não pode modificar o esquema do banco de dados original, então várias boas respostas foram fornecidas e resolvem o problema perfeitamente.
Se você puder , no entanto, modificar seu esquema, aconselho adicionar um campo em sua
customer
tabela que contenha oid
do últimocustomer_data
registro deste cliente:Consultando clientes
Consultar é tão fácil e rápido quanto pode ser:
A desvantagem é a complexidade extra ao criar ou atualizar um cliente.
Atualizando um cliente
Sempre que você deseja atualizar um cliente, você insere um novo registro na
customer_data
tabela e atualiza ocustomer
registro.Criação de um cliente
Criar um cliente é apenas uma questão de inserir a
customer
entrada e, em seguida, executar as mesmas instruções:Empacotando
A complexidade extra para criar / atualizar um cliente pode ser assustadora, mas pode ser facilmente automatizada com gatilhos.
Finalmente, se você estiver usando um ORM, isso pode ser muito fácil de gerenciar. O ORM pode se encarregar de inserir os valores, atualizar os ids e juntar as duas tabelas automaticamente para você.
Esta é a aparência do seu
Customer
modelo mutável :E seu
CustomerData
modelo imutável , que contém apenas getters:fonte
eu acho que você precisa mudar c.customer_id para c.id
senão atualizar a estrutura da tabela
fonte
Você também pode fazer isso
fonte
É uma boa ideia registrar os dados reais na tabela " customer_data ". Com esses dados você pode selecionar todos os dados da tabela "customer_data" como desejar.
fonte