tutorials.de Buch-Aktion 05/2012
ERLEDIGT
NEIN
ANTWORTEN
13
ZUGRIFFE
665
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    fixxxxxi fixxxxxi ist offline Mitglied Gold
    Registriert seit
    Jan 2009
    Beiträge
    132
    Hallo,

    ich habe ein Gewinnspiel gebastelt, bei dem die SQL Tabelle u.a. wie folgt aufgebaut ist:

    datum - user_richtig

    Nun wird bei richtiger Antwort, die UserID in die Zelle eingetragen, die dem Datum entspricht.

    1 - |123||456||789|
    2 - |123||456||789|
    3 - |123|
    4 - |789|
    ...
    24 - |456||789|

    Die Punkte die der User erreicht ergeben sich aus dem Datum. Sprich - Datum 1, Frage richtig beantwortet = 1 Punkt - Datum 24, Frage richtig beantwortet = 24 Punkte. Nun möchte ich die Punkte der einzelnen User addieren und in einer Rangliste ausgeben. Sprich das Array sortieren und im Anschluß sortieren.

    Zu meinem Ansatz:

    Wenn ich mir das richtig überlegt habe, müsste ich zuerst 24 einzelne Abfragen machen, wo ich die einzelnen userIDs, zu dem entsprechendem Datum holen:

    PHP-Code:

    //abfrage
    $ranking_sql  mysql_fetch_array(safe_query("SELECT user_richtig FROM `".PREFIX."quiz` WHERE nummer='".$datum."'"));

    //userIDs trennen
    $ranking_user   explode("||"$ranking_sql['user_richtig']); 
    Nun habe ich alle UserIDs getrennt vom jeweiligem Datum, wo sich allerdings ein weiteres Problem verbirgt. Denn die UserIDs werden in dem Format |userID| eingetragen und nicht ||userID. Dies benötige ich, damit ich bei einer Abfrage der userID entsprechend mit % arbeiten kann. Also in der Abfrage %|userID|% um einen Treffer zu erzielen. Aber bei dem explode trennt er ja bei ||, was jedoch beim ersten und letztem Inhalt des Arrays nicht zutrifft.

    Wie kann ich diese beiden Probleme lösen?

    LG
    Geändert von fixxxxxi (03.12.10 um 13:07 Uhr)
     

  2. #2
    Tim Bureck Tim Bureck ist offline Mitglied Platin
    Registriert seit
    Apr 2009
    Ort
    Düsseldorf (NRW)
    Beiträge
    508
    1. Normalform:

    Jedes Attribut der Relation muss einen atomaren Wertebereich haben.
    Quelle

    Du solltest dein Datenbankmodell da ein wenig anpassen. Du hast z.B. eine Tabelle mit den IDs deiner User (die Usertabelle vermutlich) und dann eine Relation für die Datumse, die die User gelöst haben:

    Datum|Userid
    1|123
    1|456
    2|123
    ...

    Du hast also nur eine UserID pro Datensatz. Dann kannst du mit den Aggregationsfunktionen von MySQL wunderbar arbeiten...
     

  3. #3
    fixxxxxi fixxxxxi ist offline Mitglied Gold
    Registriert seit
    Jan 2009
    Beiträge
    132
    Dafür ist es erstens zu spät, und zweitens befinden sich in der Tabelle noch weitere Werte.

    datum | frage | antwort1 | antwort2 | antwort3 | ergebnis | user_richtig | user_alle

    datum = 24
    frage = welcher buchstabe ist der erste im alphabet?
    antwort1 = B
    antwort2 = A
    antwort3 = C
    ergebnis = antwort2
    user_richtig = |123|
    user_alle = |123||456||789|

    Ich überprüfe mit dieser Tabelle zusätzlich ob der User bereits die Frage zB. beantwortet hat.

    PHP-Code:
    $i 1;
    while (
    $i <= 24) {
    $date=$i++;
    $ranking_sql  mysql_fetch_array(safe_query("SELECT user_richtig FROM `".PREFIX."quiz` WHERE nummer='".$date."'"));
    echo 
    '<br/>Datum/Punkte:'.$date++.' - UserIDs: '.$ranking_sql[0].'<br/>'

    gibt folgendes aus:

    Datum/Punkte:1 - UserIDs: |95||707||625||1255||1190|...
    Datum/Punkte:2 - UserIDs: |95||707||625||1255||1190|...
    Datum/Punkte:3 - UserIDs: |85||95||1237||637||707||1693|...
    ...

    Damit muss man doch irgendwie weiterkommen******
    Geändert von fixxxxxi (03.12.10 um 13:33 Uhr)
     

  4. #4
    Avatar von Yaslaw
    Yaslaw Yaslaw ist offline n/a
    tutorials.de Moderator
    Registriert seit
    Dec 2007
    Ort
    Winterthur(CH)
    Beiträge
    5.205
    Welch katastrophale Datenhaltung.

    Nichtsdestotrotz ist es nicht unlösbar. entweder du machst das über Reguläre Ausdrücke, mit explode und anschliessender bereinigung oder mit einem 3-Punkte-Plan.

    Hier mal der 3-Punkte-Plan
    1) Ersetzen aller '||' durch ','
    ->Resultat: ein String der mit einem '|' beginnt und mit einem ebensolchen endet. Dazwieschen sind die User durch ',' getrennt
    2) Ersetzen aller '|' durch nichts, also ''
    ->Resultat: ein komaseparierter String mit den Usern
    3) explode() mit dem Trennzeuichen ',' durchführen
    ->Resultat: Ein Array mit allen User-IDs

    Und so sieht das aus
    PHP-Code:
    $users explode(',',(str_replace('|'''str_replace('||'','$str)))); 
    Wenn du die Speicherart noch ändern kannst, dann mach aus |user||user| besser user,user. Du kannst dann in MySQL direkt mit FIND_IN_SET() direkt einen User auslesen
    Code sql:
    1
    2
    
    WHERE
        FIND_IN_SET('1255', '95,707,625,1255,1190');
     
    ---------------------------------------------------------------------------------------------------
    item: Ich habe es mir aus gesundheitlichen Gründen abgewöhnt unformatierten Code zu lesen (Auch SQL-Statements kann man formatieren!)
    item: Tutorial: [PHP][MySQL] Debug Queries
    item: Schreibt mir keine PN mit Fragen die im Forum beantwortet werden können - ich mache kein persönliches coaching
    item: Bitte zur besseren Lesbarkeit PHP-Code in [PHP]...[/PHP], SQL in [SQL]...[/SQL], Visual Basic in [VB]...[/VB] etc. schreiben

  5. #5
    fixxxxxi fixxxxxi ist offline Mitglied Gold
    Registriert seit
    Jan 2009
    Beiträge
    132
    Danke schonmal vorab. Nun hab ich folgendes, womit schonmal die einzelnen user in einzelne Arrays pro tag gegliedert werden:

    PHP-Code:
    $i 1;
    while (
    $i <= 24) {
    $date=$i++;
    $ranking_sql  mysql_fetch_array(safe_query("SELECT user_richtig FROM `".PREFIX."quiz` WHERE nummer='".$date."'"));
    $users explode(',',(str_replace('|'''str_replace('||'','$ranking_sql['user_richtig'])))); 

    echo 
    '<br/><b>Datum/Punkte:'.$date++.'.12.2010</b><br/>';

    for (
    $x 0$x sizeof($users); ++$x)
    {
    if (
    key($users)<10$key_users='0'.key($users); else $key_users=key($users);
         
         echo 
    "Arraywert: ".$key_users.", UserID: ".current($users)."<br>";
         
    next($users);
         
    }


    Ausgabe:

    ...
    Arraywert: 00, UserID: 85
    Arraywert: 01, UserID: 95

    Datum/Punkte:2.12.2010
    Arraywert: 00, UserID: 95
    Arraywert: 01, UserID: 707
    Arraywert: 02, UserID: 625
    Arraywert: 03, UserID: 1255
    Arraywert: 04, UserID: 1190
    Arraywert: 05, UserID: 184
    Arraywert: 06, UserID: 1653
    Arraywert: 07, UserID: 1303
    Arraywert: 08, UserID: 1414
    Arraywert: 09, UserID: 331
    Arraywert: 10, UserID: 259
    Arraywert: 11, UserID: 2
    Arraywert: 12, UserID: 79
    Arraywert: 13, UserID: 27
    Arraywert: 14, UserID: 762
    Arraywert: 15, UserID: 339
    Arraywert: 16, UserID: 841

    Datum/Punkte:3.12.2010
    Arraywert: 00, UserID: 85
    Arraywert: 01, UserID: 95
    ...

    Nun ist die Frage wie ich die Anzahl der einzelnen Userids addiere. Und nicht einfach nur addiere, sondern auch die Punkte der einzelnen Tage richtig addiere. Sprich wenn jemand am 2.12. richtig beantwortet hat 2 punkte addiert werden.

    Mein Ziel ist letztendlich folgende Ausgabe:

    Ranking:
    Platz 1: UserID: 85 (5 Punkte)
    Platz 2: UserID: 95 (4 Punkte)
    ...
     

  6. #6
    Avatar von Yaslaw
    Yaslaw Yaslaw ist offline n/a
    tutorials.de Moderator
    Registriert seit
    Dec 2007
    Ort
    Winterthur(CH)
    Beiträge
    5.205
    Woher kommen die Punkte? 2.12 -A 2 Punkte. wer als am 2.12. richtig hat, kriegt 2 Punkte, wer am 3.12. richtig hat kriegt 3 Punkte?
     
    ---------------------------------------------------------------------------------------------------
    item: Ich habe es mir aus gesundheitlichen Gründen abgewöhnt unformatierten Code zu lesen (Auch SQL-Statements kann man formatieren!)
    item: Tutorial: [PHP][MySQL] Debug Queries
    item: Schreibt mir keine PN mit Fragen die im Forum beantwortet werden können - ich mache kein persönliches coaching
    item: Bitte zur besseren Lesbarkeit PHP-Code in [PHP]...[/PHP], SQL in [SQL]...[/SQL], Visual Basic in [VB]...[/VB] etc. schreiben

  7. #7
    fixxxxxi fixxxxxi ist offline Mitglied Gold
    Registriert seit
    Jan 2009
    Beiträge
    132
    richtig... Tag=Punkte.
     

  8. #8
    Avatar von Yaslaw
    Yaslaw Yaslaw ist offline n/a
    tutorials.de Moderator
    Registriert seit
    Dec 2007
    Ort
    Winterthur(CH)
    Beiträge
    5.205
    PHP-Code:
    <?php 
    //Array für die Punkteliste initialisieren
    //Array('userid'=>punkte)
    $punkteliste = array();

    //SQL so umschreiben, dass das Datum und die Richtig-Liste ausgelesen werden
    $sql "SELECT datum, user_richtig FROM `".PREFIX."quiz` WHERE nummer='{$date}'";
    $resut mysql_query($result);


    while(
    $node mysql_fetch_array($result)){
        
    //Alle Users aus der Richtig-Liste extrahieren
        
    $users explode(',',(str_replace('|'''str_replace('||'','$node['user_richtig']))));
        
    //Alle User durchgehen
        
    foreach($users as $user){
            
    //Der Punkteliste die Punkte (Tag) hinzuzählen     
            
    $punkteliste[$user] = $punkteliste[$user]+date('j',strtotime($node['datum']));
        }
        
    }    
    //Die Punkteliste umgekehrt sortieren
    arsort($punkteliste);    
    //Die Rangliste erstellen
    //Array(Rang-1 => 'userid'
    $rangliste array_values($punkteliste);
    var_dump($punkteliste$rangliste);  
    ?>
     
    ---------------------------------------------------------------------------------------------------
    item: Ich habe es mir aus gesundheitlichen Gründen abgewöhnt unformatierten Code zu lesen (Auch SQL-Statements kann man formatieren!)
    item: Tutorial: [PHP][MySQL] Debug Queries
    item: Schreibt mir keine PN mit Fragen die im Forum beantwortet werden können - ich mache kein persönliches coaching
    item: Bitte zur besseren Lesbarkeit PHP-Code in [PHP]...[/PHP], SQL in [SQL]...[/SQL], Visual Basic in [VB]...[/VB] etc. schreiben

  9. #9
    fixxxxxi fixxxxxi ist offline Mitglied Gold
    Registriert seit
    Jan 2009
    Beiträge
    132
    Nochmals Danke. Jedoch ist irgendetwas nicht richtig. Zum einen gibt es ja gar keine Spalte Datum in der SQL DB. Ist das kleinere Übel, habe date zu nummer umgeschrieben.

    Was ich nicht so recht verstehe, woher nimmt Dein Code in der SQL Abfrage das $date? Weil date ist ja nirgends definiert :/ Oder sollte der Code in die while Schleife?

    Wenn ich den Code so übernehme gibt er aus:

    array(0) { } array(0) { }
     

  10. #10
    Avatar von Yaslaw
    Yaslaw Yaslaw ist offline n/a
    tutorials.de Moderator
    Registriert seit
    Dec 2007
    Ort
    Winterthur(CH)
    Beiträge
    5.205
    $date habe noch aus deinen Zeilen weiter oben.
    Ah, ich sehs jetzt, bei dir ist date eine Zahl, kein Datum.
    Ja nimm den WHERE-Teil einfach raus. etnferne weiter unten die Datumsauswahl aus dem MySQL-Datum zu der direkten Nummer.

    Ein Tipp, keine Zahl $date nennen. Keinen String $number nennen etc. Gibt nur verwirrung
     
    ---------------------------------------------------------------------------------------------------
    item: Ich habe es mir aus gesundheitlichen Gründen abgewöhnt unformatierten Code zu lesen (Auch SQL-Statements kann man formatieren!)
    item: Tutorial: [PHP][MySQL] Debug Queries
    item: Schreibt mir keine PN mit Fragen die im Forum beantwortet werden können - ich mache kein persönliches coaching
    item: Bitte zur besseren Lesbarkeit PHP-Code in [PHP]...[/PHP], SQL in [SQL]...[/SQL], Visual Basic in [VB]...[/VB] etc. schreiben

  11. #11
    fixxxxxi fixxxxxi ist offline Mitglied Gold
    Registriert seit
    Jan 2009
    Beiträge
    132
    Sorry das ich Dich noch weiter beanspruche. Es will einfach nicht klappen.

    PHP-Code:

    //Array für die Punkteliste initialisieren
    //Array('userid'=>punkte)
    $punkteliste = array();

    //SQL so umschreiben, dass das Datum und die Richtig-Liste ausgelesen werden
    $sql "SELECT nummer, user_richtig FROM `".PREFIX."quiz`";
    $result mysql_query($sql);

    while(
    $node mysql_fetch_array($result)){
        
    //Alle Users aus der Richtig-Liste extrahieren
        
    $users explode(',',(str_replace('|'''str_replace('||'','$node['user_richtig']))));
        
    //Alle User durchgehen
        
    foreach($users as $user){
            
    //Der Punkteliste die Punkte (Tag) hinzuzählen     
            
    $punkteliste[$user] = $punkteliste[$user]+($node['nummer']);
        }
        
    }    
    //Die Punkteliste umgekehrt sortieren
    arsort($punkteliste);    
    //Die Rangliste erstellen
    //Array(Rang-1 => 'userid'
    $rangliste array_values($punkteliste);
    var_dump($punkteliste$rangliste); 
    Gibt aus:

    array(26) { [""]=> int(295) [259]=> int(5) [339]=> int(5) [625]=> int(5) [95]=> int(5) [707]=> int(5) [1237]=> int(3) [85]=> int(3) [637]=> int(3) [744]=> int(3) [1412]=> int(3) [1693]=> int(3) [873]=> int(3) [732]=> int(3) [841]=> int(2) [2]=> int(2) [1653]=> int(2) [184]=> int(2) [1190]=> int(2) [1255]=> int(2) [1303]=> int(2) [1414]=> int(2) [27]=> int(2) [79]=> int(2) [331]=> int(2) [762]=> int(2) } array(26) { [0]=> int(295) [1]=> int(5) [2]=> int(5) [3]=> int(5) [4]=> int(5) [5]=> int(5) [6]=> int(3) [7]=> int(3) [8]=> int(3) [9]=> int(3) [10]=> int(3) [11]=> int(3) [12]=> int(3) [13]=> int(3) [14]=> int(2) [15]=> int(2) [16]=> int(2) [17]=> int(2) [18]=> int(2) [19]=> int(2) [20]=> int(2) [21]=> int(2) [22]=> int(2) [23]=> int(2) [24]=> int(2) [25]=> int(2) }

    Ist dies Zahl hinter int(2), int(3), int(5) die Punktezahl? Was auch immer das ist, es ist nicht das was ich möchte ;P

    *UPDATE*
    [""]=> int(295) sind das die Gesamtpunkte von allen? Wenn ich es mir genau anschaue, ist es doch das was ich möchte - zumindest teilweise. Weshalb wird das array 2x ausgegeben?
    Geändert von fixxxxxi (03.12.10 um 16:46 Uhr)
     

  12. #12
    Avatar von Yaslaw
    Yaslaw Yaslaw ist offline n/a
    tutorials.de Moderator
    Registriert seit
    Dec 2007
    Ort
    Winterthur(CH)
    Beiträge
    5.205
    Ja, das ist ide Punktezahl nach dem System wie ich es verstanden habe wie du es haben willst. Tja, dann muss wohl jemand her der versteht was du haben willst.

    Der erster Array $punkteliste setzt sich zusammen mit der userid als Schlüssel und der Punktezahl als Wert.
    Der zweite Array $rangliste ist die User als Rangliste, wobei der Schlüssel den Rang-1 ist (index beginnt bei 0) und der Wert die Userid ist.

    Irgnedwie nimmt er noch einen leeren user mit 295 Punkten. Hab ohne deine Daten zu sehen grad keien Ahnung wo der herkommt.
     
    ---------------------------------------------------------------------------------------------------
    item: Ich habe es mir aus gesundheitlichen Gründen abgewöhnt unformatierten Code zu lesen (Auch SQL-Statements kann man formatieren!)
    item: Tutorial: [PHP][MySQL] Debug Queries
    item: Schreibt mir keine PN mit Fragen die im Forum beantwortet werden können - ich mache kein persönliches coaching
    item: Bitte zur besseren Lesbarkeit PHP-Code in [PHP]...[/PHP], SQL in [SQL]...[/SQL], Visual Basic in [VB]...[/VB] etc. schreiben

  13. #13
    fixxxxxi fixxxxxi ist offline Mitglied Gold
    Registriert seit
    Jan 2009
    Beiträge
    132
    Passt soweit alles! Riesen Danke =) Kann man den ersten Wert des Arrays ausblenden?
    Geändert von fixxxxxi (03.12.10 um 17:39 Uhr)
     

  14. #14
    fixxxxxi fixxxxxi ist offline Mitglied Gold
    Registriert seit
    Jan 2009
    Beiträge
    132
    Soweit so gut. Nur gibt es ein Problem. Je mehr Leute mirmachen, desto mehr Pseudouser werden in die Rangliste eingefügt. Ich weiß nur nicht weshalb.

    PHP-Code:
    ############
    #rangliste
    ############

    if (issuperadmin($userID)) 
    {
    $punkteliste = array();
    $sql "SELECT nummer, user_richtig FROM `".PREFIX."quiz`";
    $result mysql_query($sql);
    while(
    $node mysql_fetch_array($result)){
        
    $users explode(',',(str_replace('|'''str_replace('||'','$node['user_richtig']))));
        foreach(
    $users as $user){
            
    $punkteliste[$user] = $punkteliste[$user]+($node['nummer']);
        }
    }
    arsort($punkteliste);    
    $x=0;
    echo 
    '<div style="padding:50px 0px 0px 50px;">
          - - - - -<br/><br/>Die Rangliste ist nur als Superadmin sichtbar!<br/><br/>- - - - -<br/><br/>
          <table><tr><td>Platz</td><td>Punkte</td><td>User</td><tr>'
    ;
        foreach (
    $punkteliste as $id => $rangliste) {
        
    $fragen_richtig_sql  safe_query('SELECT COUNT(*) FROM `webs_quiz` WHERE `user_richtig` LIKE \'%|'.$id.'|%\'');
        
    $fragen_richtig      mysql_result($fragen_richtig_sql,0);
        
    $fragen_gesamt_sql   safe_query('SELECT COUNT(*) FROM `webs_quiz` WHERE `user_alle` LIKE \'%|'.$id.'|%\'');
        
    $fragen_gesamt       mysql_result($fragen_gesamt_sql,0);
           echo 
    '<tr><td>'.$x++.'</td><td>'.$rangliste.'</td><td>'.getnickname_org($id).'
           <font color="#CCC">(UserID:'
    .$id.') - '.$fragen_richtig.' von '.$fragen_gesamt.' korrekt!</font></td><tr>';
         }  
    echo 
    '</table></div>';

    gibt aus:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
     - - - - -
     
    Die Rangliste ist nur als Superadmin sichtbar!
     
    - - - - -
     
    Platz   Punkte  User
    0   276 (UserID:) - 3 von 3 korrekt!
    1   15  (UserID:antwort1) - 0 von 0 korrekt!
    2   9   f!x×x×xi*nDs (UserID:95) - 3 von 3 korrekt!
    3   9   RbK (UserID:707) - 3 von 3 korrekt!
    4   7   Ncom.sax (UserID:85) - 2 von 2 korrekt!
    5   6   Nightfire (UserID:79) - 2 von 3 korrekt!
    6   6   Remus.gL (UserID:27) - 2 von 2 korrekt!
    7   5   jordeeeh (UserID:259) - 2 von 2 korrekt!
    8   5   sil3nt (UserID:339) - 2 von 3 korrekt!
    ...
    ..
    .

    Das ist meine SQL Tabellenstruktur, an der ich nun nichts mehr ändern kann, da sie bereits gefüllt ist!


    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
    -- 
    -- Tabellenstruktur für Tabelle `webs_quiz`
    -- 
     
    CREATE TABLE `webs_quiz` (
      `nummer` int(11) NOT NULL,
      `frage` varchar(500) NOT NULL,
      `antwort1` varchar(500) NOT NULL,
      `antwort2` varchar(500) NOT NULL,
      `antwort3` varchar(500) NOT NULL,
      `ergebnis` varchar(500) NOT NULL,
      `user_richtig` text NOT NULL,
      `user_falsch` text NOT NULL,
      `user_over30` text NOT NULL,
      `user_alle` text NOT NULL,
      PRIMARY KEY  (`nummer`)
    ) ENGINE=MyISAM AUTO_INCREMENT=25 DEFAULT CHARSET=utf8;

    An was kann das liegen, das diese "Pseudouser" erstellt werden?

    0 276 (UserID - 3 von 3 korrekt!
    1 15 (UserID:antwort1) - 0 von 0 korrekt!

    LG
    Geändert von fixxxxxi (04.12.10 um 12:41 Uhr)
     

Ähnliche Themen

  1. Antworten: 4
    Letzter Beitrag: 26.11.10, 11:08
  2. Addieren von 2 Arrays
    Von Sasser im Forum PHP
    Antworten: 1
    Letzter Beitrag: 06.09.10, 02:09
  3. Zahlenwerte eines Arrays addieren
    Von BillyJoe im Forum C/C++
    Antworten: 8
    Letzter Beitrag: 24.10.09, 01:26
  4. unbestimmte Anzahl Arrays addieren ?
    Von mrepox im Forum PHP
    Antworten: 9
    Letzter Beitrag: 03.09.06, 11:16
  5. 2 Arrays addieren
    Von dibe0014 im Forum PHP
    Antworten: 1
    Letzter Beitrag: 29.03.06, 16:59

Stichworte