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
  1. select  
  2.   termeknev, egysegar  
  3. from  
  4.   (select  
  5.      termeknev, ar, tipus_id  
  6.    from  
  7.      termekek  
  8.    order by  
  9.      egysegar desc  
  10.   ) as termekek  
  11. group by  
  12.   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:
  1. SELECT `t1`.`TermekNev` , `t1`.`Egysegar`  
  2. FROM `termekek` AS `t1`  
  3. INNER JOIN `termekek` AS `t2` ON `t1`.`TipusId` = `t2`.`TipusId`  
  4. GROUP BY `t1`.`TermekId`  
  5. 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.
  1. SELECT `termekek`.`TermekNev`, `termekek`.`Egysegar`  
  2. FROM   
  3.     `termekek`,  
  4.     (  
  5.         SELECT `TipusId`, MAX(`Egysegar`) AS `Egysegar`   
  6.         FROM `termekek` GROUP BY `TipusId`  
  7.     ) AS `legDragabbTermekek`  
  8. WHERE  
  9.     `termekek`.`TipusId` = `legDragabbTermekek`.`TipusId`  
  10. AND  
  11.     `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.