Tengo un cliente de mesa que almacena un customer_id, un correo electrónico y una referencia. Hay una tabla adicional customer_data que almacena un registro histórico de los cambios realizados al cliente, es decir, cuando se realiza un cambio, se inserta una nueva fila.
Para mostrar la información del cliente en una tabla, las dos tablas deben unirse; sin embargo, solo la fila más reciente de customer_data debe unirse a la tabla de clientes.
Se vuelve un poco más complicado porque la consulta está paginada, por lo que tiene un límite y un desplazamiento.
¿Cómo puedo hacer esto con MySQL? Creo que quiero poner un DISTINCT en alguna parte ...
La consulta al minuto es así-
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
Además, ¿tengo razón al pensar que puedo usar CONCAT con LIKE de esta manera?
(Aprecio que INNER JOIN podría ser el tipo incorrecto de JOIN para usar. De hecho, no tengo ni idea de cuál es la diferencia entre los diferentes JOIN. ¡Voy a investigar eso ahora!)
Respuestas:
Es posible que desee probar lo siguiente:
Tenga en cuenta que a
JOIN
es solo un sinónimo deINNER JOIN
.Caso de prueba:
Resultado (consulta sin
LIMIT
yWHERE
):fuente
Si está trabajando con consultas pesadas, es mejor que mueva la solicitud a la última fila en la cláusula where. Es mucho más rápido y se ve más limpio.
fuente
sql_no_cache set
), mientras que hacer la búsqueda en la combinación tardó varios segundos en completarse. Todavía desconcertado, pero quiero decir que no puedes discutir con resultados como ese.Suponiendo que la columna de incremento automático en
customer_data
se llamaId
, que puede hacer:fuente
Para cualquier persona que deba trabajar con una versión anterior de MySQL (anterior a 5.0 ish), no puede realizar subconsultas para este tipo de consulta. Aquí está la solución que pude hacer y pareció funcionar muy bien.
Básicamente, se trata de encontrar la identificación máxima de su tabla de datos uniéndola al cliente y luego uniendo la tabla de datos a la identificación máxima encontrada. La razón de esto es porque seleccionar el máximo de un grupo no garantiza que el resto de los datos coincida con la identificación a menos que lo vuelva a unir a sí mismo.
No lo he probado en versiones más recientes de MySQL pero funciona en 4.0.30.
fuente
EXPLAIN
indica que esto usa una tabla temporal y un ordenamiento de archivos. AgregarORDER BY NULL
al final elimina el ordenamiento de archivos.SELECT *, MAX(firstData.id), MAX(secondData.id) [...]
. Lógicamente, al cambiar aSELECT main.*, firstData2.*, secondData2.*, MAX(firstData.id), MAX(secondData.id), [...]
pude hacerlo significativamente más rápido. Esto permite que las primeras uniones lean solo del índice, en lugar de tener que leer también todos los datos del índice principal. Ahora, la solución bonita tarda solo 1,9 veces más que la solución basada en subconsultas.Sé que esta pregunta es antigua, pero ha recibido mucha atención a lo largo de los años y creo que le falta un concepto que pueda ayudar a alguien en un caso similar. Lo agrego aquí en aras de la integridad.
Si no puede modificar el esquema de su base de datos original, entonces se han proporcionado muchas buenas respuestas y resuelve el problema sin problemas.
Sin embargo, si puede modificar su esquema, le aconsejo que agregue un campo en su
customer
tabla que contengaid
el últimocustomer_data
registro de este cliente:Consultar clientes
La consulta es tan fácil y rápida como puede ser:
El inconveniente es la complejidad adicional al crear o actualizar un cliente.
Actualización de un cliente
Siempre que desee actualizar un cliente, inserte un nuevo registro en la
customer_data
tabla y actualice elcustomer
registro.Creando un cliente
Crear un cliente es solo una cuestión de insertar la
customer
entrada y luego ejecutar las mismas declaraciones:Terminando
La complejidad adicional para crear / actualizar un cliente puede ser temible, pero se puede automatizar fácilmente con activadores.
Finalmente, si está usando un ORM, esto puede ser muy fácil de administrar. El ORM puede encargarse de insertar los valores, actualizar los identificadores y unir las dos tablas automáticamente por usted.
Así es como
Customer
se vería su modelo mutable :Y su
CustomerData
modelo inmutable , que solo contiene captadores:fuente
Creo que necesitas cambiar c.customer_id a c.id
else actualizar la estructura de la tabla
fuente
También puedes hacer esto
fuente
Es una buena idea registrar los datos reales en la tabla " customer_data ". Con estos datos puede seleccionar todos los datos de la tabla "customer_data" como desee.
fuente