Autor Zpráva
stepanka
Profil *
Ahoj,

narazila jsem na takovou zvláštní věc...

Když mám dotaz

$query = "SELECT p.nazev_cz, p.nazev_en, p.id, p.kusu_skladem, p.aktivni,
                        DATEDIFF(now(),FROM_UNIXTIME(p.datum)) AS pocet_dnu_od_zalozeni,
						DATEDIFF(now(),FROM_UNIXTIME(max(o.datum2))) AS pocet_dnu,
						DATEDIFF(now(),max(o.datum)) AS pocet_dnu_od_objednavky,
						IF(o.datum2 IS NULL OR max(o.datum2)=0,0,1) AS zakoupeno,
						IF(o.datum IS NULL OR max(o.datum)=0,0,1) AS objednano							
								
               	FROM produkty p
		 				JOIN vyrobci v  ON v.id_vyrobce=p.id_vyrobce
						LEFT JOIN objednavky_polozky op ON op.id_produkt = p.id 
						LEFT JOIN objednavky o ON o.id_objednavka = op.id_objednavka 
						WHERE v.id_vyrobce='".$_GET['id_vyrobce']."' 
		 				 ".$where."
		 				GROUP BY p.id
						ORDER BY p.aktivni DESC";


a dotaz

$query = "SELECT p.nazev_cz, p.nazev_en, p.id, p.kusu_skladem, p.aktivni,
                        DATEDIFF(now(),FROM_UNIXTIME(p.datum)) AS pocet_dnu_od_zalozeni,
						DATEDIFF(now(),FROM_UNIXTIME(max(o.datum2))) AS pocet_dnu,
						DATEDIFF(now(),max(o.datum)) AS pocet_dnu_od_objednavky,
						IF(o.datum2 IS NULL OR max(o.datum2)=0,0,1) AS zakoupeno,
						IF(o.datum IS NULL OR max(o.datum)=0,0,1) AS objednano,
						p.kod_vyrobce						
								
               	FROM produkty p
		 				JOIN vyrobci v  ON v.id_vyrobce=p.id_vyrobce
						LEFT JOIN objednavky_polozky op ON op.id_produkt = p.id 
						LEFT JOIN objednavky o ON o.id_objednavka = op.id_objednavka 
						WHERE v.id_vyrobce='".$_GET['id_vyrobce']."' 
		 				 ".$where."
		 				GROUP BY p.id
						ORDER BY p.aktivni DESC";


tak ve výsledku mi každý dotaz seřadí vybrané položky jinak. Přitom jsou úplně stejné, jen v jednom vybírám z tabulky o údaj víc.

Proč tomu tak je, že seřazení je u každého dotazu jiné? Vždyť na tom, co mám v SELECTu, by nemělo vůbec záležet, nebo ne?
Kajman_
Profil *
Zkuste dát p.aktivni do group by. Ono by se správně ani neměl používat sloupeček, co není v group by nebo obalen agregační funkcí.

Pro vývoj je lepší mysql v módu, co hlídá korektní group by
http://dev.mysql.com/doc/refman/5.1/en/server-sql-mode.html#sqlmode_only_full_group_by
Kajman_
Profil *
A druhá věc je, že když nezadáte jednoznačné seřazení, tak si to při rovnosti už může vrátit db jak chce a klidně pokaždé jinak.
stepanka
Profil *
Kajman_

Ono by se správně ani neměl používat sloupeček, co není v group by nebo obalen agregační funkcí.
Jestli tady této větě rozumím správně, tak můžu udělat SELECT pouze těch sloupců, které dám následně do GROUP BY, nebo budou obaleny agregační funkcí? To je divné... Často přece uživatel potřebuje vytáhnout data ze sloupců, ale nepotřebuje na tento sloupec aplikovat žádnou agregační funkci, ani tento sloupec nemůže dát do GROUP BY..
Kajman_
Profil *
Jak potom může db vědět který z mnoha údajů má dát? Proč by ho nemohl dát do group by?

Ale spíš to bude tím nejednoznačným seřazením. Máte prostě neaktivní a pak aktivní, ale při jiném selectu máte taky neaktivní a pak aktivní, ale v rámci stejné aktivity různě seřazené, ne? To je naprosto korektní chování.
Kajman_
Profil *
Samozřejmě ten sloupec do group by přidávat jen, pokud už tam nějaké group by je definované.
stepanka
Profil *
Kajman_

Proč by ho nemohl dát do group by?
Protože když dám sloupec p.aktivni do GROUP BY, tak mi to místo stovky produktů vytáhne dva - jeden aktivní a jeden neaktivní.

Já chápu, že db neví, který aktivní produkt vyplivnout jako první, když jiné řazení za "ORDER BY p.aktivni DESC" nemá. Ale ta databáze si to prostě nějak seřadila, a když dám 8x za sebou reload stránky, je to seřazené vždy stejně.

Na druhé stránce pak používám ten druhý dotaz (vybírám pouze o jeden údaj víc), ale tam se mi to seřadí úplně jinak. Ale když dám zase 8x za sebou reload, je to seřazené zase vždy pořád stejně (nijak se to nepřehazuje)... A když v druhém dotazu odeberu ten jeden přidaný údaj, řadí mi to oba dotazy naprosto stejně (i po osmi reloadech).

Tím pádem jsem usoudila, že ten jeden přidaný řádek do SELECTu tam dělá nějaký zmatek, protože bez něj fungují oba dotazy stejně.. Ale proč, to nevím...

Vyřešila jsem to trochu neelegantně - dotazem navíc. Spíš by mě zajímal princip, kterým si to MySQL zpracovává, protože mi to přijde zvláštní..
Kajman_
Profil *
Protože když dám sloupec p.aktivni do GROUP BY, tak mi to místo stovky produktů vytáhne dva
GROUP BY p.id, p.aktivni


Ale ta databáze si to prostě nějak seřadila, a když dám 8x za sebou reload stránky, je to seřazené vždy stejně.
To ale neznamená, že po deváté to dá také tak! Z definice si pořadí u neseřaditelných záznamů může vyplivnout libovolně! U těch dvou dotazů to prostě využije. Není v tom žádná záhada.
stepanka
Profil *
Kajman_
ok ok, nekřič :-) Díky za vysvětlení i za všechny reakce.
Toto téma je uzamčeno. Odpověď nelze zaslat.