Ho due tabelle nel database delle vendite MySQL:MySQL intra-gruppo aggrega con sotto-query - ha suggerito dati di test aggiornati
Ordini tavolo:
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 tavolo:
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);
Ora devo selezionare per ogni cliente, l'ultimo prezzo che acquistano ogni prodotto.
Il modo più semplice per farlo è quello di utilizzare una sottoquery:
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;
Risultato:
CustomerID ProductID LastPrice ultimoData
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
Ora la domanda; come è possibile ottenere lo stesso risultato se voglio evitare sub-query, tabelle temporanee o una vista, voglio solo usare i join; questa query è una piccola parte di una query molto più ampia e la sub-query è altamente inefficiente.
Ho provato questa query:
SELEZIONA o1.CustomerID, od1.ProductID, od1.Price AS LastPrice, o1.OrderDate AS ultimoData
DA Ordini sinistra come o1 ENTRA OrderDetails come OD1 ON o1.ID = od1.OrderID
GROUP BY CustomerID, ID prodotto
ORDINA PER ID cliente, ID prodotto;
ma dà un risultato diverso:
CustomerID ProductID LastPrice ultimoData
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
Come si vede, LastPrice & LastDate non sono corretti.Ho anche provato il suggerimento di Allen, ma il risultato è:
CustomerID ProductID LastPrice ultimoData
1 1 4 2012-06-30 00:00:00
1 2 20 2012-06-30 00:00: 00
prima query dai risultati di risposta prodotti duplicati di Spencer:
CustomerID ProductID LastPrice ultimoData
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
altre risposte tutte utilizzano sub-query, che sto cercando di evitare.
qualche suggerimento?
codice molto strutturato e molto pulito, grazie! È possibile riscriverlo per fare lo stesso senza sub-query? – user1499268
la prima query mostra cliente/prodotto duplicato nel risultato, non solo l'ultimo acquisto. puoi testare i nuovi dati che ho postato – user1499268
@user: sto lavorando con i nuovi dati che hai postato. La seconda query nella mia risposta (che ha le viste in linea) sembra restituire il set di risultati corretto. Con i nuovi dati, vedo che la prima query nella mia risposta sta restituendo un set di risultati errato, sto cercando di scoprire cosa c'è che non va. Questo è l'ultimo che ho scritto, come tentativo di riscrivere la query utilizzando le viste in linea (fondamentalmente per ottenere CustomerID e OrderDate al livello OrderDetails.) – spencer7593