As Linhas Armazenando o Group-wise Máximo de um Certo Campo
Para cada ítem, encontre o(s) fornecedor(s) com o maior preço.
No SQL-99 (e MariaDB ou superior), o problema pode ser solucionado com uma subconsulta como esta:
SELECT article, dealer, price FROM shop s1 WHERE price=(SELECT MAX(s2.price) FROM shop s2 WHERE s1.article = s2.article);
Em versões anteriores a do MariaDB é melhor fazê-lo em diversos passos:
- Obtenha a lista de pares (article,maxprice).
- Para cada ítem, obtenha os registros correspondentes que tenham o maior preço.
Isto pode ser feito facilmente com uma tabela temporária e um join:
CREATE TEMPORARY TABLE tmp ( article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL, price DOUBLE(16,2) DEFAULT '0.00' NOT NULL); LOCK TABLES shop READ; INSERT INTO tmp SELECT article, MAX(price) FROM shop GROUP BY article; SELECT shop.article, dealer, shop.price FROM shop, tmp WHERE shop.article=tmp.article AND shop.price=tmp.price; UNLOCK TABLES; DROP TABLE tmp;
Se você não usar uma tabela TEMPORÁRIA
, você deve bloquear também a tabela tmp
.
Posso fazer isto com uma única query?
Sim, mas somente com um truque ineficiente chamado truque MAX-CONCAT
:
SELECT article, SUBSTRING( MAX( CONCAT(LPAD(price,6,'0'),dealer) ), 7) AS dealer, 0.00+LEFT( MAX( CONCAT(LPAD(price,6,'0'),dealer) ), 6) AS price FROM shop GROUP BY article; +---------+--------+-------+ | article | dealer | price | +---------+--------+-------+ | 0001 | B | 3.99 | | 0002 | A | 10.99 | | 0003 | C | 1.69 | | 0004 | D | 19.95 | +---------+--------+-------+
O último exemplo pode, é claro, ser feito de uma maneira mais eficiente fazendo a separação da coluna concatenada no cliente.