Autor Zpráva
Vanama
Profil
Mám docela náročný web na databázi a tak se snažím trochu optimalizovat skript, ale s následujícím si prostě neporadím a tak se obracím na vás.

Mám tuhle query, která vypisuje seznam her:

			$query = "SELECT #__puarcade_games.id as id,numplayed,#__puarcade_games.description,#__puarcade_games.imagename,
      #__puarcade_games.published,gamename,title,reverse_score,scoring,window,height,width,contentratingid,folderid,name,total_votes,total_value,count(score) as scorecount,(total_value/total_votes) as rating
       FROM #__puarcade_games INNER JOIN #__puarcade_folders on (#__puarcade_folders.id = folderid)
        LEFT JOIN #__puarcade_ratings on (#__puarcade_games.id = #__puarcade_ratings.gameid)
         LEFT JOIN #__puarcade on (#__puarcade_games.id = #__puarcade.gameid)
          WHERE #__puarcade_games.published = '1' AND folderid = '$fid' GROUP BY #__puarcade.gameid ORDER BY id DESC ".$limit;


a chtěl bych to spojit s tímhle dotazem, který ke každé vypisované hře z dotazu výše vypisuje nejlepší skóre + hráče, který jej vytvořil (bohužel může být problém v tom, že nejlepší skóre může být i nejnižší hodnota - reverse_score). Následující query mám právě ve výpisu mezi foreach což je kámen úrazu.

			$query = "Select #__puarcade.score,#__puarcade.date,#__puarcade.played_time,#__puarcade.userid,#__users.name,#__users.username FROM #__puarcade left join #__users on (#__puarcade.userid = #__users.id) WHERE gameid LIKE '$game->id' AND published = '1' ORDER BY score ".$ordering.",played_time asc, date asc LIMIT 1";


a pokud by to bylo ještě možné, chtěl bych tam vložit ještě query, která zjišťuje skóre hráče, který si stránku prohlíží. Opět je samostatně ve výpisu her mezi foreach.

			$query = "Select score from #__puarcade WHERE userid='$my->id' AND gameid='$game->id' ";



Díky tomu jak je to teď napsaný, je to 17 dotazů na db při zobrazení jedné stránky z výpisem her. Kdyby to šlo na jeden, bylo by to super. Díky za rady, věřím, že to pro vás nebude těžké to zkloubit :)
tiso
Profil
Vanama - jedno z riešení je denormalizácia. Inak - ťažko radiť, bez znalosti tabuliek a vzťahov medzi nimi. Scháma databázy by nebola?
Vanama
Profil
#__puarcade >  userid 	score 	ip 	gameid 	date 	published 	id 	played_time 	playcount

#__puarcade_games >  id 	gamename 	title 	height 	width 	description 	numplayed 	imagename 	filename 	background 	published 	reverse_score 	folderid 	scoring 	window 	contentratingid 	author 	time_played

#__users > id 	name 	username 	email 	password 	usertype 	block 	sendEmail 	gid 	registerDate 	lastvisitDate 	activation 	params



Vypsal jsem tři tabulky, které je potřeba spojit, zbytek asi není třeba. Jinak id v tabulce users je stejné jako userid a id v puarcade_games je stejné jako gameid.
Vanama
Profil
Dá se moje situace řešit jinak než tou denormalizací? Je to poměrně zaběhnutý web a nechci se v tom moc šťourat.

Možná by vám pro představu mohla pomoct názorná ukázka toho co vlastně chci vypisovat jedním selectem. Tu najdete na Zábava-online.cz buď na hlavní stránce nebo dál ve výpisech kategorií.

Za každou radu či ještě lépe hotové řešení z celého srdce děkuji.
Kajman_
Profil *
Jak si najít řádky s maximem či minimem ke každé hře je ve faq. Ten výsledek pak připojíte poddotazem k současnému dotazu. Stejně tak si můžete připojit skóre čtenáře.
tiso
Profil
Vanama - myslel som zníženie celkového počtu dotazov pri zobrazení stránky, nie tento konkrétny dotaz.
Vanama
Profil
Jak si najít řádky s maximem či minimem ke každé hře je ve faq. Ten výsledek pak připojíte poddotazem k současnému dotazu. Stejně tak si můžete připojit skóre čtenáře.


Vím, že můžu použít max(score) a min(score), ale nevím jak mám napsat do jednoho dotazu, aby to vybíral podle hodnoty reverse_score.

Ten poddotaz mám napsat nějak jako SELECT neco, neco2, (Select score from #__puarcade WHERE userid='$my->id') as myscore FROM ... ?
Nejsem v tom moc zběhlej, bude to tak nějak fungovat?
Vanama
Profil
Tak jsem zkoušel ten poddotaz a samozřejmě nefunguje protože vrací víc jak jednu hodnotu. Potřeboval by to tedy zgroupnout podle gameid v dotazu a to je zas to co ještě neumím :(
Vanama
Profil
Tak jsem si pohrál s tím poddotazem na zobrazení skóre hráče co si stránku prohlíží a zaznamenal jsem nakonec úspěch :)

$query = "SELECT #__puarcade_games.id as id,numplayed,#__puarcade_games.description,#__puarcade_games.imagename,
      #__puarcade_games.published,gamename,title,reverse_score,scoring,window,height,width,contentratingid,folderid,name,total_votes,total_value,count(score) as scorecount, t.my_score as myscore,(total_value/total_votes) as rating
       FROM #__puarcade_games INNER JOIN #__puarcade_folders on (#__puarcade_folders.id = folderid)
        LEFT JOIN #__puarcade_ratings on (#__puarcade_games.id = #__puarcade_ratings.gameid)
         LEFT JOIN #__puarcade on (#__puarcade_games.id = #__puarcade.gameid)
          LEFT JOIN (select gameid, score my_score,count(id) pocet from #__puarcade where userid = '$my->id' group by gameid) t on (t.gameid = #__puarcade_games.id)         
           WHERE #__puarcade_games.published = '1' AND folderid = '$fid' GROUP BY #__puarcade.gameid ORDER BY $cookieorder ".$limit;


Akorát s tím max, min skóre si lámu hlavu jak to udělat. Napadlo mě udělat to jako dva poddotazy kde v jednom by bylo select max(score) ... WHERE reverse_score = 0 a v druhém select min(score) ... WHERE reverse_score = 1, ale myslím, že to nebude nejlepší řešení :(
Kajman_
Profil *
Nepomůže něco jako?

if(reverse_score,min(score),max(score))
Vanama
Profil
Jo, to je přesně to co potřebuju, díky!

Teď ještě nějak musím dát dohromady ten zbytek. Snad si s tím nějak poradím.

Díky moc!
Vanama
Profil
Tak bohužel se obávám, že to nedám dohromady :(

Splácal jsem následující dotaz, ale nevím jak do druhého poddotazu poslat informaci o sloupci reverse_score. Navíc nevím jestli můžu ještě v poddotazu spojovat další tabulku.

$query = "SELECT #__puarcade_games.id,numplayed,#__puarcade_games.description,#__puarcade_games.imagename,
      title,reverse_score,scoring,folderid,name,total_votes,total_value,(total_value/total_votes) as rating,count(score) as scorecount,t.my_score as myscore, hiscore.highscore as highscore,hiscore.userid as userid, hiscore.username as username
       FROM #__puarcade_games INNER JOIN #__puarcade_folders on (#__puarcade_folders.id = folderid)
        LEFT JOIN #__puarcade_ratings on (#__puarcade_games.id = #__puarcade_ratings.gameid)
         LEFT JOIN #__puarcade on (#__puarcade_games.id = #__puarcade.gameid) 
          LEFT JOIN (select gameid, score my_score from #__puarcade where userid = '$my->id' group by gameid) t on (t.gameid = #__puarcade_games.id)
           LEFT JOIN (select gameid, if(reverse_score,min(score),max(score)) as highscore,userid,username from #__puarcade where score = highscore group by gameid) hiscore on (hiscore.gameid = #__puarcade_games.id) INNER JOIN #__users hiscore on (#__puarcade.userid = #__users.id)         
           WHERE #__puarcade_games.published = '1' GROUP BY #__puarcade_games.id ORDER BY rating DESC, total_votes DESC ".$limit;
Vanama
Profil
Tak jsem splácal další paskvil, který sice mysql veme, ale ty 3 hodnoty, kvůli kterým se to snažím předělat (highscore,userid a username), jsou NULL. Navíc provedení dotazu trvá asi 13 vteřin :(

SELECT jos_puarcade_games.id,numplayed,jos_puarcade_games.description,jos_puarcade_games.imagename,
      title,scoring,folderid,name,total_votes,total_value,(total_value/total_votes) as rating,count(score) as scorecount,t.my_score as myscore, hiscore.highscore as highscore,hiscore.userid as userid, hiscore.username as username
       FROM jos_puarcade_games INNER JOIN jos_puarcade_folders on (jos_puarcade_folders.id = folderid)
        LEFT JOIN jos_puarcade_ratings on (jos_puarcade_games.id = jos_puarcade_ratings.gameid)
         LEFT JOIN jos_puarcade on (jos_puarcade_games.id = jos_puarcade.gameid) 
          LEFT JOIN (select gameid, score my_score from jos_puarcade where userid = 62 group by gameid) t on (t.gameid = jos_puarcade_games.id)
           LEFT JOIN (select reverse_score,if(reverse_score,min(score),max(score)) as highscore,gameid,played_time,userid,username from jos_puarcade_games RIGHT JOIN jos_puarcade on (jos_puarcade_games.id = gameid) LEFT JOIN jos_users on (userid = jos_users.id) group by gameid  ORDER BY highscore,played_time ASC LIMIT 1) hiscore on (hiscore.gameid = jos_puarcade_games.id)         
           WHERE jos_puarcade_games.published = '1' GROUP BY jos_puarcade_games.id ORDER BY rating DESC, total_votes DESC


Pomožte mi prosím někdo :(

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: