Získání řádku s maximální hodnotou

Školení, která pořádám

Tradiční způsob, jak v SQL získat řádek obsahující maximální hodnotu nějakého sloupce, je pomocí subselectu. Ty jsou v MySQL ale až od verze 4.1, takže ve starších verzích je to potřeba řešit jinak.

<?php
// subselect
mysql_query("SELECT * FROM tabulka WHERE sloupec = (SELECT MAX(sloupec) FROM tabulka)");

// řešení na aplikační úrovni
$max_sloupec = mysql_result(mysql_query("SELECT MAX(sloupec) FROM tabulka"), 0);
mysql_query("SELECT * FROM tabulka WHERE sloupec = '" . mysql_real_escape_string($max_sloupec) . "'");

// trik
mysql_query("SELECT * FROM tabulka ORDER BY sloupec DESC LIMIT 1");
?>

Dlužno podotknout, že první dva způsoby mohou vrátit i více řádků, třetí naopak vždy nejvýše jeden, což je ale většinou přesně to, co chceme. Co se rychlosti týče, jsou všechny dotazy při existujícím indexu nad sloupcem sloupec dostatečně rychlé. Druhý způsob bude o něco pomalejší, pokud MySQL server běží na jiném stroji a režie dotazů do databáze je nezanedbatelná.

Přijďte si o tomto tématu popovídat na školení Návrh a používání MySQL databáze.

Jakub Vrána, Výuka, 11.5.2005, diskuse: 10 (nové: 0)

Diskuse

Jan Menšík:

A ze existuje Amerika vite?

varen buffet:

si ty ale pako

Voidless:

Treti typ dotazu muze vracet jen jeden zaznam? Co takhle "SELECT * FROM tabulka ORDER BY sloupec DESC LIMIT X", pro X>1?

ikona Jakub Vrána OpenID:

To by samozřejmě šlo, problém je ale v tom, že počet řádek s maximální hodnotou nemusí být dopředu známý.

Jan Dosoudil:

A co použít SELECT max() FROM tabulka?

ikona Jakub Vrána OpenID:

Zadání zní "získat řádek obsahující maximální hodnotu", ne "získat maximální hodnotu". Je to potřeba pro dotazy typu "zjistit ID nejdražšího výrobku".

Honza Hučín:

Dovolím si upozornit na obecné řešení vypsání všech řádků s N-tou největší hodnotou.
http://suplik.petnik.cz/index.php?cl=223

teddy:

"pokud MySQL server běží na jiném stroji a režie dotazů do databáze je nezanedbatelná."

To je tak velky rozdil mezi spojenim na localhost pres socket a na jiny server pres TCP/IP ?

Michal:

No já bych řekl, že jo, protože každý dotaz ten server, kde běží PHP musí jí "po drátech" na jiný stroj s SQL a teď záleží, jaká je konektivita, jestli je to v jedom subnetu nebo ne.

Každopádně se asi myslí, že stroje jsou v jedné síti, připojené 100Mbit, pak ten rodíl rychlosti může být zanedbatelný, ale určitě tam bude.

Mirek:

A co použítí HAVING ?
SELECT * MAX(sloupec) AS max_value
FROM tabulka
HAVING sloupec = max_value

Diskuse je zrušena z důvodu spamu.

avatar © 2005-2024 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.