Ska göra en fisketävling för en fiskeklubb.
Tävlingen går ut på att få så stora fiskar som möjligt av olika arter, sedan skall poäng räknas efter ett visst system:
I varje art får de 15 största fiskarna poäng från 15 för den största ned till 1 för den 15:e. Bara medlemmens 5 största fiskar i den aktuella arten ger poäng. Fiskar med samma vikt delar på poängen för de placeringarna ( Om t.ex. de två största fiskarna väger lika mycket får de (15+14)/2=14,5 poäng). Det kan bli mer än 15 fiskar som får poäng om plats 15 delas av flera fiskar, de får då dela på 1 poäng.
Tabellen består av:
Id
Namn
Art
Vikt
Poäng
Jag har med hjälp av ett webbformulär och PHP fått till det så att fiskar kan matas in via webben, problemet kommer när jag ska beräkna poängen för varje Id. Först måste man ju jämföra med medlemmens anmälda fiskar av den arten. Platsar den inte bland medlemmens 5 största fiskar blir ju poängen noll.
Platsar den så måste man ju jämföra med alla Id av den arten och uppdatera poängen för alla Id av den arten om den går in bland de 15 största.
Jag är helt färsk på programmering, databaser och framförallt SQL/PHP så om någon kan hjälpa mig i rätt riktning så skulle jag bli lycklig!
LarsGMedlem sedan dec. 200012 464 inlägg Vilken databashanterare använder du? Om man vill lösa allt i SQL så blir det ganska komplicerat och det är inte säkert att det ens går att lösa (beroende på begränsningar i aktuell DBMS.)
Här kom svaren snabbt!
Jag använder mySQL-admin. Kanske det skulle vara smidigare att på något sätt lösa det med PHP för att uppdatera databasen varje gång någon har matat in data i databasen?
Som sagt jag är helt färsk på det här med databaser så jag har inte en aning om hur jag ska lösa det.
Förlåt. phpMyAdmin (2.5.4) heter den ju. En webb-baserad variant som mitt webbhotell tillhandahåller. MySQL 3.23.58 är databasen.
LarsGMedlem sedan dec. 200012 464 inlägg Okej, då det är Mysql så kan vi utesluta en helt SQL-baserad lösning (en sådan är att föredra av prestandaskäl).
Några påpekanden
Jag skulle använda två tabeller
persons
name
total -- totalpoäng
catches
name
art
weight
points
Jag skulle inte döpa en kolumn till poäng (åäö ställer bara till problem.)
$art etc hänvisar till de värden som du hämtar från den första select-satsen.
//För varje post
// select * from catches
while ( $row = mysql_fetch_row($q) ) {
// Hämta hur många som har en fisk
// som är större i samma art
// select count(*) from catches where Art = '$art'
// and $name /= $name and weight > $weight )
//
// $c1 innehåller antalet
if ( $c1 > 15 ) $point = 0;
else {
// Hämta hur många som har en fisk som
// är lika i samma art
// select count(*) from catches
// where Art = '$art'
// and name /= $name
// and weight = $vikt )
//
// $c2 innehåller antalet
$point = 15 - $c1;
if ( $points <= 0 ) $point = 1;
if $c1 + $c2 <= 15 $point += $c2*0.5;
}
// uppdatera
// update catches set point = $point
// where art = $art and name = $name
}
// Alla poster uppdaterade
//hämta alla poster och räkna samman poäng
// select * from catches where point > 0
// order by name,point desc
$name = '';
$totalp = 0;
$c = 0;
while ( $row = mysql_fetch_row($q)) {
if ( $name != $row["namn"] ) {
if ( !$totalp ) {
// update persons set total = $totalp
// where name = $name
}
$totalp = 0;
$c = 0;
}
if ( $c < 5 ) {
$totalp += $row(["points"]);
$c++;
}
}
if ( !$totalp ) {
// update persons set total = $totalp
// where name = $name
}
// hämta list med rangordning
//
// select name,total from persons order by total desc
Nu saknas all kod för att utföra själva SQL-satserna och hämtar data till variabler men det finns ett flertal exempel på hur man gör det i PHP-manualen.
HakanSMedlem sedan dec. 2002529 inlägg Jag skulle göra en tabell med följande:
Fiskare
Art
Vikt
Poängen beräknas och visas då någon vill se dem. På så sätt behöver inte alla poster i databasen uppdateras när någon lägger in en fångstanmälan.
Tack för all hjälp!
Jag funderar vad som egentligen är bäst att göra, fick den här lösningen i ett annat forum (precis som HakanS föreslår så räknar den ut poängen när någon frågar efter den):
<?php
define("FISKAR_PER_ART_O_FISKARE", 5);
define("FISKAR_PER_ART", 15);
$start = microtime();
error_reporting(E_ALL);
ini_set("display_errors", "1");
$link = mysql_connect ("xxx.com", "xxx", "xxx");
mysql_select_db("xxx", $link);
$arter = array();
$fiskare = array();
$query = "SELECT *
FROM interna
ORDER BY
art, vikt DESC";
$result = mysql_query($query, $link);
while($f = mysql_fetch_array($result,MYSQL_ASSOC)) {
$art = $f['art'];
$namn = $f['namn'];
if (!isset($fiskare[$namn][$art]['nof'])) {
$fiskare[$namn][$art]['nof']=0;
}
$fiskare[$namn][$art]['nof']++;
if ($fiskare[$namn][$art]['nof'] <= FISKAR_PER_ART_O_FISKARE) {
$arter[$art][] = array('namn' => $f['namn'],
'vikt' => $f['vikt']
);
}
}
reset($arter);
$next=current($arter);
while ($next) {
$curr_art = key($arter);
$pos=0;
$shared_points=0;
while (isset($arter[$curr_art][$pos]) && $pos < FISKAR_PER_ART) {
while ((isset($arter[$curr_art][$pos+$shared_points+1]['vikt'])) && ($arter[$curr_art][$pos]['vikt'] == $arter[$curr_art][$pos+$shared_points+1]['vikt'])) {
$shared_points++;
}
$points=$points=FISKAR_PER_ART-$pos-0.5*$shared_points;
$curr_pos=$pos;
while ($pos <= ($curr_pos+$shared_points)) {
$arter[$curr_art][$pos]['points']=$points;
$pos++;
}
$shared_points=0;
}
$next = next($arter);
}
va($arter);
print(microtime()-$start);
function va(& $arr) {
print("<pre>");
print_r($arr);
print("</pre>");
}
?>