Avatar billede kimkochrasmussen Nybegynder
15. august 2010 - 10:52 Der er 7 kommentarer og
1 løsning

Summere flere resultater

Hej

Er lidt i tvivl om jeg skal poste her eller under PHP - men antager det er her.
Jeg sidder og laver lidt frivilligt arbejde med et point system til noget skoleatletik.
Jeg er på INGEN måde en haj til at skrive sql-kald, så jeg håber på en venlig sjæl...

Jeg har to tabeller med bl.a. følgende felter:

DELTAGER
id
fornavn
efternavn
skole
klasse
koen

RESULTAT
uid (fortløbende)
did (referer til deltager.id)
point
cat

Jeg skal nu havde lavet en rangliste over bedste klasser ud fra point (kommer længere nede).
Klasserne kan findes ved at se på eleverne i deltager-tabellen. MEN en klassse er både defineret ved felterne skole og klasse (der kan godt være flere elever der går i 6A, men er det på forskellgie skoler, er det jo forskellige klasser. klasserne på de enkelte skoler hedder ikke nødvendigvis det samme).

Klassens pointtal skal beregnes som:
De 5 bedste (målt på resultat.point) drenge (deltager.koen = M) i hver resultat.cat (som der er 3 af)
PLUS
De 5 bedste (målt på resultat.point) piger (deltager.koen = K) i hver resultat.cat (som der er 3 af)

Altså består en klassens pointtal af 30 elev resultater der skal summeres.
Ønsket er så en rangliste over klasserne.

Nogen der kan hjælpe?
Avatar billede ggxdg Nybegynder
15. august 2010 - 13:05 #1
Skal det være som 1 opslag? Eller må køn deles op?
Flg. er for M:

"SELECT deltager.klasse AS dklasse,deltager.skole AS dskole,
  IN("SELECT SUM(resultat.point)
    FROM deltager
    INNER JOIN resultat
    ON deltager.id=resultat.did
    WHERE deltager.klasse = dklasse
    AND deltager.skole = dskole
    ORDER BY resultat.point DESC
    LIMIT 5") AS rpoint
  FROM deltager
  WHERE deltager.koen = 'M'
  GROUP BY deltager.skole,deltager.klasse"

Det kan sikkert gøres simplere, og jeg har ingen idé om det vil fungere...
Avatar billede kimkochrasmussen Nybegynder
15. august 2010 - 13:19 #2
TAK

Nej det behøves nok ikke at være i 1 opslag - hvis det efterfølgende output på php-siden kan slå det sammen.
Det kan jeg ikke gennemskue om man kan med det du skriver....(?)
Avatar billede ggxdg Nybegynder
15. august 2010 - 13:55 #3
Man kan vel bare lave opslaget 2 gange, 1 med M og en med K.

klaPoint($koen = "M")
{
  $query = "SELECT deltager.klasse AS dklasse,deltager.skole AS dskole, IN("SELECT SUM(resultat.point) FROM deltager INNER JOIN resultat ON deltager.id=resultat.did WHERE deltager.klasse = dklasse AND deltager.skole = dskole ORDER BY resultat.point DESC LIMIT 5") AS rpoint FROM deltager WHERE deltager.koen = '".$koen."' GROUP BY deltager.skole,deltager.klasse";
  $result = mysql_query($query);
  while($row = mysql_fetch_assoc($result))
  {
    echo "<br />Skole: ".$row['dskole']."<br />Klasse: ".$row['dklasse']."<br />Resultat: ".$row['rpoint']."<br />";
  }
  if ($koen = "M") { klaPoint("K"); }
}

Som sagt, jeg aner ikke om det fungerer, men skriv lige når du har testet det :)
Avatar billede groyk Novice
15. august 2010 - 21:23 #4
Jeg vil klart anbefale et opslag. Udemiddelbart ser ggxdg´s første SELECT ikke helt dum ud. Men det afhænger naturligvis af MySQL version om den virker.

Har du prøvet den første ide, og hvilket output giver den dig?
Avatar billede ggxdg Nybegynder
15. august 2010 - 22:25 #5
#4 Er den "nestede" SELECT helt håbløs siden du kun nævner den første? :P
Avatar billede kimkochrasmussen Nybegynder
15. august 2010 - 23:50 #6
TAK for forslagene.

Desværre fik jeg en fejl, nemlig:

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 'IN('SELECT SUM(resultat.point) FROM deltager INNER JOIN resultat ' at line 2



Jeg fik derefter en kammerat til at kigge på det også, og han kom op med følgende, som jeg naturligvis deler med jer her.

Men tak til ggxdg for at lede os på sporet - smid et svar hvis du vil havde pointene


Koden (til php) blev:
// Henter alle klasserne ud af DB'en
$query = mysql_query('SELECT del.skole, del.klasse
          FROM deltager del
          WHERE 1
          GROUP BY del.skole, del.klasse');


// Opretter et array med alle de forskellige kategorier
$catArr = array('K', 'L', 'S');

$i =0;
// Looper over klasserne, for at finde deres point
while ($KlasseRow =  mysql_fetch_array( $query ))
{
$i ++;
$ResArray[$i]['point'] = 0;
  // Looper over kategorierne
  foreach ($catArr as $key )
  {
      // Den klasse og skole vi arbejder med
    $skole= $KlasseRow['skole'];
      $klasse= $KlasseRow['klasse'];

      // Henter klassens fem bedste drenges score ud
      $ResQuery = mysql_query("
              SELECT sum.skole, sum.klasse, SUM(sum.point) as point
              FROM (
                  SELECT d.skole, d.klasse, d.fornavn, d.efternavn, r.cat, r.point
                  FROM deltager d, resultat r
                  WHERE d.id=r.did
                  AND d.klasse= '$klasse'
                  AND d.skole= '$skole'
                  AND d.koen = 'M'
                  AND r.cat = '$key'
                  ORDER by r.point DESC
                  LIMIT 5
                  ) sum
              WHERE 1
        GROUP BY sum.skole
              ");

      // Resultatet af SQL'en ind i temp arrayet
      $tempDreng = mysql_fetch_array( $ResQuery );

      // Henter klassens fem bedste pigers score ud
      $ResQuery = mysql_query("
              SELECT sum.skole, sum.klasse, SUM(sum.point) as point
              FROM (
                  SELECT d.skole, d.klasse, d.fornavn, d.efternavn, r.cat, r.point
                  FROM deltager d, resultat r
                  WHERE d.id=r.did
                  AND d.klasse= '$klasse'
                  AND d.skole= '$skole'
                  AND d.koen = 'K'
                  AND r.cat = '$key'
                  ORDER by r.point DESC
                  LIMIT 5
            ) sum
              WHERE 1
              GROUP BY sum.skole
              ");

      // Resultatet af SQL'en ind i temp arrayet
      $tempPige = mysql_fetch_array( $ResQuery );

      // Resultaterne sættes ind i array
      $ResArray[$i]['skole']  = $tempDreng['skole'];
      $ResArray[$i]['klasse'] = $tempDreng['klasse'];
      $ResArray[$i]['point']  +=  ($tempDreng['point'] + $tempPige['point']);

  }
}

// Sorterer arrayet
$ResArray = sortByInteger($ResArray, 'point');

function sortByInteger(&$Array, $field) {
  $sort = "return -strnatcmp(\$p1['$field'], \$p2['$field']);";
  usort($Array, create_function('$p1,$p2', $sort));
  return $Array;
}

// Printer resultaterne
foreach ($ResArray as $res){
  echo $res['skole'] . " ";
  echo $res['klasse'] . " ";
  echo $res['point'];
  echo "<br>";   
    }
Avatar billede ggxdg Nybegynder
16. august 2010 - 08:02 #7
Du kan bare tage halvdelen eller hvad du nu lyster selv :)
Avatar billede groyk Novice
18. august 2010 - 20:50 #8
Hej ggxdg

Er jo samme SQL når jeg kigger nærmere efter :-)
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
Computerworld tilbyder specialiserede kurser i database-management

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