ugrás a tartalomhoz

MySQL: GROUP BY probléma: minden terméktipus legdrágább termékének a neve?

Anonymous · 2006. Május. 11. (Cs), 16.41
Lehet, hogy csak a fáradtság teszi, de nem találom a megoldást a következő problémára. Adott a következő tábla:
TermekId TipusId TermekNev Egysegar
-----------------------------------
       1       1 félcipő       5000
       2       1 csizma       10000
       3       2 sál           1000

Ebből a táblából szeretném visszakapni terméktípusonként a legdrágább termékek nevét. A következő lekérdezést alkottam:
SELECT `TermekNev`, MAX(`Egysegar`) AS `Ar` FROM `termekek` GROUP BY `TipusId`

Namost ennek a lekérdezésnek az eredménye ez lesz:
TermekNev     Ar
----------------
félcipő    10000
sál         1000

Vagyis nem a maximális árhoz tartozó termék nevét kapom vissza, hanem az első termék nevét, amely ahhoz a csoporthoz tartozik. Miért van ez, és hogy tudnám az engem érdeklő termék nevét visszakapni?

.bonga
 
1

subquery vagy sztringműveletek

Anonymous · 2006. Május. 11. (Cs), 17.01

select
  termeknev, egysegar
from
  (select
     termeknev, ar, tipus_id
   from
     termekek
   order by
     egysegar desc
  ) as termekek
group by
  tipus_id
ez mysql 4.1-től működőképes. előző verziókban bűvészkedni kell a sztringműveletekkel...
ez azért van, mert a group by mindig az első sorokat szedi össze, előtte valahogy rendezni kell a táblát.

gex
3

jah

Anonymous · 2006. Május. 11. (Cs), 17.05
Igen, a subquery-re én is gondoltam, de kedves szolgáltatómnál még a 4.0.20-as mysql dübörög, ezért kellett valami más módszert találni.
Azért köszönöm, ez is jó!

.bonga
2

Sikerült!

Anonymous · 2006. Május. 11. (Cs), 17.02
Végre megtaláltam a megoldást: önmagával kell JOIN-olni a táblát, úgy már jó lesz:
SELECT `t1`.`TermekNev` , `t1`.`Egysegar`
FROM `termekek` AS `t1`
INNER JOIN `termekek` AS `t2` ON `t1`.`TipusId` = `t2`.`TipusId`
GROUP BY `t1`.`TermekId`
HAVING `t1`.`Egysegar` = MAX(`t2`.`Egysegar`)
Szóval csak ennyi. Gondoltam leírom, hátha mást is érdekel.

.bonga
4

mysql sucks

Hodicska Gergely · 2006. Május. 12. (P), 08.49
Azért az ilyen querykkel vigyázz, mert ezek egy tisztességes DB-ben hibát adnak vissza. Szabvány szerint (persze tök logikusan) a select listában GROUP BY esetén csak olyan mezők szerepelhetnek aggregátor függvény nélkül, amelyek szerint megy a group by.

És ez így is van rendjén, hisz a group by által összefogott sorok egy halmazt alkotnak, amely nem rendezett, nem tudhatod, hogy épp melyik elemét fogod visszakapni.


Felhő
5

xD

Pisti20 · 2010. Aug. 6. (P), 09.57
Nem számít, a lényeg hogy megoldottad, gg :):P
6

Bár sok éves topic, de ezt

inf · 2012. Május. 2. (Sze), 21.16
Bár sok éves topic, de ezt dobta ki a kereső, úgyhogy írok bele egy szerintem jó megoldást.

SELECT `termekek`.`TermekNev`, `termekek`.`Egysegar`
FROM 
	`termekek`,
	(
		SELECT `TipusId`, MAX(`Egysegar`) AS `Egysegar` 
		FROM `termekek` GROUP BY `TipusId`
	) AS `legDragabbTermekek`
WHERE
	`termekek`.`TipusId` = `legDragabbTermekek`.`TipusId`
AND
	`termekek`.`Egysegar` = `legDragabbTermekek`.`Egysegar`
Nyilván érdemes felindexszelni a táblát, hogy ne legyen lassú, de MAX-al így oldható meg. Valamiért én nem szeretem a JOIN-t, és ha csak lehet kerülöm, egyéni fóbia... :-)

A hiba az eredeti lekérésedben, hogy nem veszed figyelembe, hogy a GROUP BY-al csoportot hozol létre, és utána a MAX ebből a csoportból választ. Ha nem választasz ki egy konkrét sort a csoportból, akkor mindig a csoport legelső sorához tartozó értéket fogja visszaadni, mint a név esetén is.