Avatar billede llSimsll Nybegynder
27. oktober 2009 - 09:28 Der er 25 kommentarer og
1 løsning

Vælger en bruger

Jeg har en tabel med top score over forskellige spil.
Hver gang et spil er færdig smider den en række ind i tabellen med brugernavn, spil id, bruger id og score.

Jeg henter top scorer ud sådan;
SELECT user, game_id, MAX( score ) FROM game_scores GROUP BY gname

Problemet er bare at selvom der er 100 forskellige brugernavne derinde, bliver KUN det første brugt hele vejen igennem, så når bruger 2 har topscore i spil 2 får bruger 1 æren.

Håber i forstår :)
27. oktober 2009 - 10:17 #1
Jeg indsaa svagheden i det svar jeg leverede paa dit spoergsmaal i gaar, "SELECT user, game_id, MAX( score ) FROM game_scores GROUP BY gname".  Du spurgte ogsaa videre om muligheden for at have ikke den hoejeste men for eksempel de ti hoejeste scores i hver slags game.

Vi skal igang med subqueries saa som SELECT * FROM abc WHERE def = (SELECT ... FROM ...).

Jeg er i gang med at undersoege det og forventer at kunne levere svar, men det tager maaske lige lidt tid.
Avatar billede llSimsll Nybegynder
27. oktober 2009 - 10:20 #2
Christian_Belgien > Fantastisk, jeg venter i spænding :)
Avatar billede Slettet bruger
27. oktober 2009 - 15:47 #3
Jeg har forsøgt mig med nedenstående select. I tilfælde hvor flere brugere har fået samme high score, vil de alle blive selected. Jeg har ikke testet det:

SELECT
    `game_scores`.`user`,
    `game_scores`.`game_id`,
    `high_score`.`score`
FROM
    `game_scores` INNER JOIN (
        SELECT
            MAX(`score`) AS `score`,
            `gname`
        FROM
            `game_scores`
        GROUP BY
            `gname`
    ) AS `high_score` ON (
        `game_scores`.`score` = `high_score`.`score` AND
        `game_scores`.`gname` = `high_score`.`gname`
    )

Alternativt kan du game_id til at gruppere:

SELECT
    `game_scores`.`user`,
    `game_scores`.`game_id`,
    `high_score`.`score`
FROM
    `game_scores` INNER JOIN (
        SELECT
            MAX(`score`) AS `score`,
            `game_id`
        FROM
            `game_scores`
        GROUP BY
            `game_id`
    ) AS `high_score` ON (
        `game_scores`.`score` = `high_score`.`score` AND
        `game_scores`.`game_id` = `high_score`.`game_id`
    )
Avatar billede llSimsll Nybegynder
27. oktober 2009 - 16:32 #4
Det virker helt perfekt!

Men hvad med mit andet spørgsmål?
Sådan at jeg har en faktisk liste med 10 topscorer per spil?
Avatar billede Slettet bruger
27. oktober 2009 - 17:57 #5
Det kan lade sig gøre, men så skal du nok ud i at bruge variable i din query. Hvis jeg var dig, ville jeg gå efter den simplere løsning, hvor du først selecter alle games, looper dem igennen og i den loop select dine top 10 scores.
Avatar billede llSimsll Nybegynder
27. oktober 2009 - 21:31 #6
kvadratrodenaf1 > Kan du give et eksempel?
Avatar billede llSimsll Nybegynder
28. oktober 2009 - 15:04 #7
#3 > Scorer samme bruger, den samme score, i samme spil, tager den begge resultater. Hvordan undgår man så det? :)
Avatar billede llSimsll Nybegynder
28. oktober 2009 - 15:06 #8
#7> Man kan vel forhindre at hvis man scorer det samme som man har gjordt i spillet, smider den det ikke ind i db'en?
Avatar billede Slettet bruger
28. oktober 2009 - 15:17 #9
Du kan hente top 10 sådan her:

SET @number := 0, @game_id := 0;
SELECT
    `user`,
    `game_id`,
    `score`
FROM
    (
        SELECT
            `user`,
            `score`,
            @number := IF(@game_id = `game_id`,@number + 1,1) AS `number`,
            @game_id := `game_id` AS `game_id`
        FROM
            `game_scores`
        ORDER BY
            `game_id`,
            `score` DESC
    ) AS `tmp`
WHERE
    `number` <= 10;
Avatar billede llSimsll Nybegynder
28. oktober 2009 - 21:10 #10
mysql_fetch_array(): supplied argument is not a valid MySQL result resource.....
Avatar billede Slettet bruger
28. oktober 2009 - 22:27 #11
Og hvad er fejlen?
mysql_query($sql) or die(mysql_error());
29. oktober 2009 - 22:03 #12
llSimsll, jeg er tilbage.  Jeg har i mellemtiden studeret teorien om sub-selects fra mit gamle SQL kursus.  For at proeve det ud har jeg lavet nedenstaaende mini-database.

I mellemtiden har kvadratrodenaf1 produceret en loesning (eller to loesninger) paa problemet at faa de hoejeste scores i hvert type game.  Og ja, de virker i min mysql med min database.

(Det kan formuleres en anelse kortere med den foelgende formulering (der ogsaa viser navnet paa de forskellige typer games:)
SELECT gname, game_id, user_id, user, score
FROM game_scores gs
WHERE SCORE = (
  SELECT MAX(score)
  FROM game_scores
  WHERE gname = gs.gname
  GROUP BY gname)

Yderligere har kvadratrodenaf1 produceret en loesning paa at finde de 10 hoejeste scores for hver type game ved hjaelp af variable.  Saa langt er jeg ikke kommet i min teori, men jeg har afprovet det i min mysql og det virker.

Men, som du siger, af en eller anden grund virker det ikke hvis det kaldes fra php.  Traaden endte med at kvadratrodenaf1 bad om at faa fejlen specificeret with "..or die(mysql_error).  Det har jeg gjort, og fejlmeldingen er den foelgende: "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT `user` , `game_id` , `score` FROM ( SELECT `user` , `score` , @numbe' at line 3".  Saa den samme kode som virker direkte i mysql virker tilsyneladende ikke naar den kaldes fra php.  Jeg forstaar ikke hvorfor.  Kvadratrodenaf1, forstaar du det?

Men hvis man ved hvilke typer games der er i databasen saa kan opgaven at finde de hoejeste 10 af hver type loeses med UNION.  Hvis det stadig har interesse skal jeg proeve i morgen tidligt at lave saadan en loesning.

Her er min database:

id    gname    game_id    user_id    user  score
1     golf      1     1     user1 25
2      golf      1     2     user2 50
3      golf      1     3     user3 33
4      golf      1     4     user4 17
5      golf      1     5     user5 10
6      go 2      2     1    user1 100
7      go 2      2     2    user2 90
8      go 2      2     3    user3 55
9      go 2     2     4    user4 112
10      go 2     2     5    user5 111
11      ludo     3     1     user1 1000
12      ludo     3     2     user2 1111
13      ludo     3     3     user3 993
14      ludo     3     4     user4 1210
15      ludo     3     5     user5 800

Du kan se resultatet af min query i http://christianjorgensen.be/game_scores.php (jeg har ikke faaet tabbene til at passe sammen, jeg skal ogsaa studere mere php/http) og ogsaa fejlmeldingen fra kvadratrodenaf1's kode.
Avatar billede Slettet bruger
30. oktober 2009 - 09:27 #13
Det er nok fordi php ikke kan håndtere 2 queries i en request.

Prøv at køre dem sådan her:
mysql_query("SET @number := 0, @game_id := 0;");
mysql_query("SELECT
    `user`,
    `game_id`,
    `score`
FROM
    (
        SELECT
            `user`,
            `score`,
            @number := IF(@game_id = `game_id`,@number + 1,1) AS `number`,
            @game_id := `game_id` AS `game_id`
        FROM
            `game_scores`
        ORDER BY
            `game_id`,
            `score` DESC
    ) AS `tmp`
WHERE
    `number` <= 10;");

Og en lille note til:
SELECT gname, game_id, user_id, user, score
FROM game_scores gs
WHERE SCORE = (
  SELECT MAX(score)
  FROM game_scores
  WHERE gname = gs.gname
  GROUP BY gname)


Hvis du har disse data:
gname    score
et      100
to      100
to      200

vil alle sammen blive selected fordi inner-selecten:
  SELECT MAX(score)
  FROM game_scores
  WHERE gname = gs.gname
  GROUP BY gname

vil outputte 100 og 200.
Avatar billede Slettet bruger
30. oktober 2009 - 09:29 #14
Ahh.. glem min lille note - jeg så ikke gname = gs.gname.
Jeg troede ikke man kunne referere outer-selecten fra inner-selecten.. Jeg plejer at lave det med joins.. Så never mind min lille kommentar :-)
30. oktober 2009 - 09:55 #15
Det virkede ikke med UNION (hvad kvadratrodenaf1 vel allerede vidste.)

Men jeg har lavet en php scrift med en function getGames($game, $antal).  Hvis man siger:  echo getGames("'golf'", 3); echo getGames("'go'", 3); echo getGames("'ludo'",3) saa viser den i browseren for hver af de tre typer games de tre hoejeste scorer.  Det er ikke idealt, men kvadratrodenaf1's scrift der virker i mysql virker som du har konstateret ikke i php.

Hvis du kikker paa http://christianjorgensen.be/game_scores.php kan du see foerst de hoejeste scores i alle typer game (ogsaa naar man foejer nye typer games til), dernaest de tre hoejeste scores i golf, go, og ludo, og derefter fejlmeldingen fra kvadratrodenaf1's script.  Min kode er nedenfor.

Jeg har udtoemt min viden nu (og har udvidet min viden mens jeg har arbejdet med dette spoergsmaal.)  Maaske er tiden inde til at afslutte spoergsmaalet her og saa maaske starte et nyt spoergsmaal:  "jeg har denne kode der virker i mysql men giver denne error message i php...".  Points skal vel gaa til kvadratrodenaf1 (jeg har betalt af paa at pointene i det forige spoergsmaal vist blev givet foer spoergsmaalet var endeligt besvaret.)

<html>
<head>
  <title></title>
</head>

<body>
<?
$link = mysql_connect ('christianjorgensen.be.mysql', 'christianjoygen', 'dnyBKKbe') or die(mysql_erorr());
mysql_select_db('christianjoygen') or die('Could not select database');

//****Hoejeste score for alle typer game***

echo "Hoejeste score for hver type game:<br/>";
echo "gname\tgame_id\tuser_id\tuser\tscore<br/>";
$query = "
SELECT gname, game_id, user_id, user, score
FROM game_scores gs
WHERE SCORE = (
SELECT MAX(score)
  FROM game_scores
  WHERE gname = gs.gname
  GROUP BY gname)";
$result = mysql_query($query);
while ($row = mysql_fetch_array($result))
{
  echo $row[0] . "\t" . $row[1] . "\t" . $row[2] . "\t" . $row[3] . "\t" . $row[4] . "\t" . $row[5];
  echo "<br/>";
}
echo "<br/><br/>";

//****Hoejeste 3 scores for hvert angivet game type***

function getGames($game, $antal)
{
  $query = "
          SELECT gname, game_id, user_id, user, score
          FROM game_scores
          WHERE gname = " . $game . "
          ORDER BY score DESC
          LIMIT 0,$antal";
  $result = mysql_query($query);
  $linie = "";
  while ($row = mysql_fetch_array($result))
  {
    $linie .= $row[0] . "\t" . $row[1] . "\t" . $row[2] . "\t" . $row[3] . "\t" . $row[4] . "\t" . $row[5] . "<br/>";
  }
  return $linie;
}

echo "Hoejeste 3 scores for hver type game:<br/>";
echo "gname\tgame_id\tuser_id\tuser\tscore<br/>";
echo getGames("'golf'", 3);
echo getGames("'go'", 3);
echo getGames("'ludo'", 3);
echo "<br/><br/>";

//****Kode der virker i mysql men ikke i php***
$query = "SET @number := 0, @game_id := 0;
SELECT
    `user`,
    `game_id`,
    `score`
FROM
    (
        SELECT
            `user`,
            `score`,
            @number := IF(@game_id = `game_id`,@number + 1,1) AS `number`,
            @game_id := `game_id` AS `game_id`
        FROM
            `game_scores`
        ORDER BY
            `game_id`,
            `score` DESC
    ) AS `tmp`
WHERE
    `number` <= 10; ";
$result = mysql_query($query) or die(mysql_error());
echo "user\tgame_id\tscore<br/>";
while ($row = mysql_fetch_array($result1))
{
  echo $row[0] . "\t" . $row[1] . "\t" . $row[2] . "\t" . $row[3];
  echo "<br/>";
}

//****slut****
mysql_close($link);
?>
Avatar billede Slettet bruger
30. oktober 2009 - 11:55 #16
Har i prøvet at dele op i to queries?


mysql_query("SET @number := 0, @game_id := 0;");

mysql_query("SELECT
    `user`,
    `game_id`,
    `score`
FROM
    (
        SELECT
            `user`,
            `score`,
            @number := IF(@game_id = `game_id`,@number + 1,1) AS `number`,
            @game_id := `game_id` AS `game_id`
        FROM
            `game_scores`
        ORDER BY
            `game_id`,
            `score` DESC
    ) AS `tmp`
WHERE
    `number` <= 10;");
30. oktober 2009 - 12:59 #17
Hvordan integrerer man det i php-siden?  Jeg har proevet nedenstaaende, men jeg var spaendt paa resultatet, for hvordan ved "$result = mysql_query($query) or die(mysql_error());" hvilken af de to mysql_query den skal bruge?  Men den giver ikke laengere syntax error, den trykker bare "user game_id score" ud.  Det vil sige (tror jeg) at queryen bliver accepteret af mysql men resulterer i intet.  Til gengaeld giver den foelgende fejlmelding naar jeg fylder den ind direkte i mysql:  "#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'mysql_query("SET @number := 0, @game_id := 0;")' at line 1"

Dette hvad jeg gjorde i php:

mysql_query("SET @number := 0, @game_id := 0;");

mysql_query("SELECT
    `user`,
    `game_id`,
    `score`
FROM
    (
        SELECT
            `user`,
            `score`,
            @number := IF(@game_id = `game_id`,@number + 1,1) AS `number`,
            @game_id := `game_id` AS `game_id`
        FROM
            `game_scores`
        ORDER BY
            `game_id`,
            `score` DESC
    ) AS `tmp`
WHERE
    `number` <= 10;"); 

$result = mysql_query($query) or die(mysql_error());
echo "user\tgame_id\tscore<br/>";
while ($row = mysql_fetch_array($result1))
{
  echo $row[0] . "\t" . $row[1] . "\t" . $row[2] . "\t" . $row[3];
  echo "<br/>";
}
Avatar billede Slettet bruger
30. oktober 2009 - 13:49 #18
Det skal være:

mysql_query("SET @number := 0, @game_id := 0;") or die(mysql_error()); //Den første query opretter temporary variables for den aktive connection som skal bruges i den anden query.

$result = mysql_query("SELECT
    `user`,
    `game_id`,
    `score`
FROM
    (
        SELECT
            `user`,
            `score`,
            @number := IF(@game_id = `game_id`,@number + 1,1) AS `number`,
            @game_id := `game_id` AS `game_id`
        FROM
            `game_scores`
        ORDER BY
            `game_id`,
            `score` DESC
    ) AS `tmp`
WHERE
    `number` <= 10;") or die(mysql_error());

echo "user\tgame_id\tscore<br/>";
while ($row = mysql_fetch_array($result1))
{
  echo $row[0] . "\t" . $row[1] . "\t" . $row[2] . "\t" . $row[3];
  echo "<br/>";
}
30. oktober 2009 - 14:29 #19
Halleluja, det virker (dvs hvis man i "while" aendrer til $result i stedet for $result1.)

Jeg har tilladed mig at rette til "number <= 3" fordi der kun er 5 vaerdier for hver game i min minidatabase, men saa giver det foelgende:

user game_id score
user2 1 50
user3 1 33
user1 1 25
user4 2 112
user5 2 111
user1 2 100
user4 3 1210
user2 3 1111
user1 3 1000
31. oktober 2009 - 19:53 #20
IlSimsli, er du staaet af?  Dit sidste indlaeg var for tre dage siden (en evighed her paa eksperten) mens kvadratrodenaf1 og jeg har rodet rundt med dit problem hvilket kvadratrodenaf1 har loest, som min test viser.

Er tiden maaske inde til at slutte spoergsmaalet?  Det giver god orden, og saa staar spoegsmaalet ikke laengere som aabent i min liste af indlaeg.  (Maaske skulle en eller anden (ikke jeg) opfordres til at lave et svar.
Avatar billede llSimsll Nybegynder
01. november 2009 - 12:30 #21
Jeg har desværre ikke fået mail om at der er indlæg :S
Jeg bukker og takker meget for jeres flotte arbejde! :)
Avatar billede llSimsll Nybegynder
01. november 2009 - 12:33 #22
Hvad så hvis jeg vil have en overskrift for hver spil og dernæst de 10 højeste?

Jeg syntes det bliver en smule uoverskuelig hvordan det smides ind.
Avatar billede llSimsll Nybegynder
01. november 2009 - 13:14 #23
#22 lige meget, jeg valgte at lave 3 topscorer for hvert spil.
02. november 2009 - 12:00 #24
IlSimsli, du bukker og takker, men lukker du spoergsmaalet?  Det giver god orden og saa staar det ikke laengere som aabent paa min liste af indlaeg.  Bed om et svar fra kvadratrodenaf1 (eller giv dig selv pointene).
Avatar billede llSimsll Nybegynder
04. november 2009 - 16:37 #25
Jeg venter sådan set også bare på et svar :)
Det har været super fedt at i hjalp så meget!
Avatar billede Slettet bruger
04. november 2009 - 19:26 #26
svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester