Tengo dos tablas en la base de datos de ventas de MySQL:MySQL dentro de los grupos agregados sin sub-consultas - sugirió datos de prueba actualizada
órdenes tabla:
CREATE TABLE salestest.`orders` (
`ID` int(11) unsigned NOT NULL auto_increment,
`OrderDate` datetime NOT NULL,
`CustomerID` int(11) unsigned NOT NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `ID` (`ID`),
KEY `OrderDate` (`OrderDate`),
KEY `CustomerID` (`CustomerID`)
) ENGINE=InnoDB;
INSERT INTO salestest.orders VALUES
(1, '2012-04-15', 1),
(2, '2012-05-20', 1),
(3, '2012-06-30', 1);
OrderDetails tabla:
CREATE TABLE salestest.`OrderDetails` (
`ID` int(11) unsigned NOT NULL auto_increment,
`OrderID` int(11) unsigned NOT NULL,
`ProductID` int(11) unsigned NOT NULL,
`Price` double NOT NULL default '0',
PRIMARY KEY (`ID`),
UNIQUE KEY `ID` (`ID`),
KEY `OrderID` (`OrderID`),
KEY `ProductID` (`ProductID`),
CONSTRAINT `OrderID_fk` FOREIGN KEY (`OrderID`) REFERENCES `orders` (`ID`)
) ENGINE=InnoDB;
INSERT INTO salestest.OrderDetails VALUES
(1, 1, 1, 2),
(2, 1, 2, 15),
(3, 1, 3, 22),
(4, 2, 1, 3),
(5, 2, 2, 17),
(6, 2, 3, 23),
(7, 2, 4, 40),
(8, 3, 1, 4),
(9, 3, 2, 20);
Ahora tengo que seleccionar para cada cliente el último precio que compra cada producto.
La manera más fácil de hacerlo es mediante el uso de una subconsulta:
SELECT od2.CustomerID,od2.ProductID, od2.Price AS LastPrice, od2.OrderDate AS LastDate
FROM (SELECT o1.ID, o1.CustomerID, o1.OrderDate, od1.ProductID, od1.Price
FROM orders AS o1
LEFT JOIN OrderDetails as od1 ON o1.ID=od1.OrderID
ORDER BY OrderDate DESC) AS od2
GROUP BY CustomerID, ProductID
ORDER BY CustomerID, ProductID;
Resultado:
CustomerID ProductID LastPrice LastDate
1 1 4 2012-06-30 00:00:00
1 2 20 2012-06-30 00:00:00
1 3 23 2012-05-20 00:00:00
1 4 40 2012-05-20 00:00:00
Ahora la pregunta; cómo es posible obtener el mismo resultado si quiero evitar sub-consultas, tablas temporales o una vista, solo quiero usar uniones; esta consulta es una pequeña parte de una consulta mucho más grande, y tener subconsulta es altamente ineficiente.
me trataron esta consulta:
SELECT o1.CustomerID, od1.ProductID, od1.Price AS LastPrice, o1.OrderDate AS LastDate
partir de las órdenes izquierdo como o1 ÚNETE OrderDetails como OD1 EN o1.ID = od1.OrderID
GROUP BY CustomerID, ProductID
ORDER BY CustomerID, ProductID;
pero da un resultado diferente:
CustomerID ProductID LastPrice LastDate
1 1 2 2012-04-15 00:00:00
1 2 15 2012-04-15 00: 00:00
1 3 22 2012-04-15 00:00:00
1 4 40 2012-05-20 00:00:00
Como se ve, LastPrice & LastDate no son correctos.También probé la sugerencia de Allen, pero el resultado es:
CustomerID ProductID LastPrice LastDate
1 1 4 2012-06-30 00:00:00
1 2 20 2012-06-30 00:00: 00
primera consulta de los resultados de respuesta productos duplicados de Spencer:
CustomerID ProductID LastPrice LastDate
1 3 22 2012-04-15 00 : 00: 00
1 3 23 2012-05-20 00:00:00
1 4 40 2012-05-20 00:00:00
1 1 4 2012-06-30 00:00:00
1 2 20 2012-06-30 00:00:00
otras respuestas todas usan la sub consulta, que estoy tratando de evitar.
alguna sugerencia?
código muy estructurado y muy limpio, ¡gracias! ¿Es posible reescribirlo para hacer lo mismo sin ninguna subconsulta? – user1499268
la primera consulta muestra clientes/productos duplicados en el resultado, no solo la última compra. Puedes probar los nuevos datos que publiqué – user1499268
@user: estoy trabajando con los nuevos datos que publicaste. La segunda consulta en mi respuesta (que tiene las vistas en línea) parece devolver el conjunto de resultados correcto. Con los nuevos datos, veo que la primera consulta en mi respuesta es devolver un conjunto de resultados incorrecto, estoy tratando de encontrar lo que está mal con él. Esa es la última que escribí, como un intento de reescribir la consulta usando las vistas en línea (básicamente para obtener el CustomerID y el OrderDate en el nivel OrderDetails). – spencer7593