J'ai une table client qui stocke un customer_id, un e-mail et une référence. Il existe une table supplémentaire customer_data qui stocke un enregistrement historique des modifications apportées au client, c'est-à-dire qu'une nouvelle ligne est insérée en cas de modification.
Afin d'afficher les informations client dans une table, les deux tables doivent être jointes, mais seule la ligne la plus récente de customer_data doit être jointe à la table customer.
Cela devient un peu plus compliqué dans la mesure où la requête est paginée, donc a une limite et un décalage.
Comment puis-je faire cela avec MySQL? Je pense que je veux mettre un DISTINCT là-dedans quelque part ...
La requête à la minute est comme ça-
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
De plus, ai-je raison de penser que je peux utiliser CONCAT avec LIKE de cette manière?
(J'apprécie qu'INNER JOIN puisse être le mauvais type de JOIN à utiliser. Je n'ai en fait aucune idée de la différence entre les différents JOIN. Je vais examiner cela maintenant!)
Réponses:
Vous pouvez essayer ce qui suit:
Notez que a
JOIN
n'est qu'un synonyme deINNER JOIN
.Cas de test:
Résultat (requête sans
LIMIT
etWHERE
):la source
Si vous travaillez avec des requêtes lourdes, il vaut mieux déplacer la demande de la dernière ligne dans la clause where. C'est beaucoup plus rapide et semble plus propre.
la source
sql_no_cache set
), alors que la recherche dans la jointure a pris plusieurs secondes. Toujours dérouté, mais je veux dire que vous ne pouvez pas discuter avec des résultats comme celui-là.En supposant que la colonne d'auto-incrémentation
customer_data
est nomméeId
, vous pouvez faire:la source
Pour toute personne qui doit travailler avec une ancienne version de MySQL (pré-5.0 ish), vous ne pouvez pas faire de sous-requêtes pour ce type de requête. Voici la solution que j'ai pu faire et cela a semblé très bien fonctionner.
Il s'agit essentiellement de trouver l'ID maximum de votre table de données en le joignant au client, puis de joindre la table de données à l'ID maximum trouvé. La raison en est que la sélection du maximum d'un groupe ne garantit pas que le reste des données correspond à l'ID, sauf si vous le rejoignez sur lui-même.
Je n'ai pas testé cela sur les versions plus récentes de MySQL mais cela fonctionne sur 4.0.30.
la source
EXPLAIN
indique que cela utilise une table temporaire et un tri de fichiers. L'ajoutORDER BY NULL
à la fin supprime le tri de fichiers.SELECT *, MAX(firstData.id), MAX(secondData.id) [...]
. Logiquement, en passant à,SELECT main.*, firstData2.*, secondData2.*, MAX(firstData.id), MAX(secondData.id), [...]
j'ai pu le rendre beaucoup plus rapide. Cela permet aux premières jointures de lire uniquement à partir de l'index, plutôt que d'avoir à lire toutes les données de l'index primaire. Maintenant, la jolie solution ne prend que 1,9 fois plus de temps que la solution basée sur les sous-requêtes.Je sais que cette question est ancienne, mais elle a retenu beaucoup d'attention au fil des ans et je pense qu'il manque un concept qui pourrait aider quelqu'un dans un cas similaire. Je l'ajoute ici par souci d'exhaustivité.
Si vous ne pouvez pas modifier votre schéma de base de données d'origine, de nombreuses bonnes réponses ont été fournies et résolvent très bien le problème.
Si vous pouvez cependant modifier votre schéma, je vous conseillerais d'ajouter un champ dans votre
customer
table qui contientid
le derniercustomer_data
enregistrement de ce client:Interroger les clients
L'interrogation est aussi simple et rapide que possible:
L'inconvénient est la complexité supplémentaire lors de la création ou de la mise à jour d'un client.
Mettre à jour un client
Chaque fois que vous souhaitez mettre à jour un client, vous insérez un nouvel enregistrement dans la
customer_data
table et mettez à jour l'customer
enregistrement.Créer un client
Créer un client consiste simplement à insérer l'
customer
entrée, puis à exécuter les mêmes instructions:Emballer
La complexité supplémentaire pour créer / mettre à jour un client peut être redoutable, mais elle peut facilement être automatisée avec des déclencheurs.
Enfin, si vous utilisez un ORM, cela peut être très facile à gérer. L'ORM peut se charger d'insérer les valeurs, de mettre à jour les identifiants et de joindre automatiquement les deux tables pour vous.
Voici à quoi
Customer
ressemblerait votre modèle mutable :Et votre
CustomerData
modèle immuable , qui ne contient que des getters:la source
je pense que vous devez changer c.customer_id en c.id
else mettre à jour la structure de la table
la source
Vous pouvez également le faire
la source
C'est une bonne idée de consigner les données réelles dans la table " customer_data ". Avec ces données, vous pouvez sélectionner toutes les données de la table "customer_data" comme vous le souhaitez.
la source