Ankündigung

Einklappen
Keine Ankündigung bisher.

Mysql id anhand des nutzers auslesen und nächste/letzte erhalten?

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Mysql id anhand des nutzers auslesen und nächste/letzte erhalten?

    Hey, ich habe ein kleines Logik Problem und wollte mal fragen ob mir jemand dabei helfen kann.

    Ich mag aus meiner Datenbank eine Nachricht auslesen. Diese hat folgende werte [id, user_id, text].
    Nun rufe ich anhand der id [5] die nachricht von dem Benutzer [2] auf. Dieser Benutzer hat auch noch Nachricht id [1,4] aktuelle id [5] und noch [8,10,25].
    Was ich möchte, dass ich die nächte & vorherige id erhalte und ausgeben kann. In dem Beispiel also id [4 & 8].

    Wie kann ich das lösen. Mir kommt gerade keine idee wie ich das von der Logik her umsetzten kann.
    Über hilfe würde ich mich freuen.

  • #2
    $sql = "SELECT * FROM `Nachricht` WHERE `user_id` = 2";
    $stmt = $pdo -> query($sql);
    $user_msg = $stmt -> fetchAll(PDO::FETCH_ASSOC);

    Habe der betreffenden Tabelle mal den Namen 'Nachricht' verpasst :-)

    Sollte im Ergebnis einen Array '$user_msg" erzeugen der alle Informationen (*) sammelt bei denen 'user_id' in der Tabelle 'Nachricht' die Nummer 2 ist. Da er alle Informationen (*) sammelt sollten nun im Array der Reihe nach auch die ID's aller Nachrichten von 'user_id' 2 befinden. Diese sollten unter $user_msg[laufende Nummer][id] dann abrufbar sein.

    $user_msg[0][id] -> 4
    $user_msg[1][id] -> 5
    $user_msg[2][id] -> 8
    $user_msg[3][id] -> 10
    $user_msg[4][id] -> 25

    Jetzt könntest du via php abfragen welche Kommentare vorher waren (< aktueller ID) oder danach kamen (> aktueller ID)

    Oder du lässt dies mySQL machen indem du den Vergleich als Operator im Statement verwendest:

    $sql = "SELECT * FROM `Nachricht` WHERE `user_id` = 2 AND `id` < 5";

    PS: Nicht erprobt, rein aus dem Kopf. Könnten Syntaxfehler drin sein :-) Aber die Logik sollte passen....
    ________
    Megabyte66
    ________

    Kommentar


    • #3
      Entschuldige falls ich mich etwas schlecht ausgedrückt habe. Ich habe ja bereits eine Abfrage wo ich mir alle Nachrichten hole und damit auch die Id's.
      Ich habe die Id's in einem Array, da ich die noch für etwas anderes benötige, nun komme ich an diesem Punkt aber nicht weiter.
      Ich habe schon ein paar rechnungen versucht, mit abfragen versucht, aber alles kommt nicht zu dem Ergebnis.
      Dafür fehlt mir gerade irgendwie die lögische Lösung.

      Hier einmal zum Verständniss
      Code:
      array(9){
          [0]=> string(1) "1"
          [1]=> string(1) "2"
          [2]=> string(1) "7"
          [3]=> string(2) "13"
          [4]=> string(2) "14" // Soll als Vorheriger ausgegeben werden
          [5]=> string(2) "18" // Aktiver Eintrag
          [6]=> string(2) "28" // Soll als Nächster ausgegeben werden
          [7]=> string(2) "35"
          [8]=> string(2) "36"
      }

      Kommentar


      • #4
        Die id vom aktuellen Beitrag hast du ja. Dann frage alle Beiträge ab mit allen ids. Dann holst du dir den Index vom aktuellen Beitrag und dann Index - 1 und + 1. natürlich noch prüfen ob du nicht out of Range kommst.

        Kommentar


        • #5
          Direkt über ein MySQL query und rowcount geht bestimmt auch

          Kommentar


          • #6
            Danke, das wort Index hat mich gerade auf die Lösung gebracht. Ich habe mir jetzt einfach den Index von der Aktuellen Nachricht geholt, dann abgefragt ob vorher, nachher ein weiterer Wert im Array steht und lasse den zurückgeben.
            Nun habe ich noch etwas weiteres mit den Nachrichten vor, in meinem ACP (Admin Control Panel) habe ich einen Log für jede gesendete Nachricht. Problem dabei ist, dass wenn es eine Nachricht an mehrere Nutzer gibt, taucht der Log Logischerweise mehrfach auf. Das mag ich verhindern, indem ich beim auslesen aus der Datenbank das ganze Bündel und dann als einen Eintrag ausgebe.

            Am liebsten hätte ich dann gerne auch noch alle 'user_id', 'is_read' & 'deleted' Werte für jede Nachricht.
            Die Nachricht an sich ist gleich, heißt [Type, Title, Text] & [created](fast kleine unterschiede im sekunden bereich) sollten identisch sein.
            Wobei ich mir Text gerne freihalten würde, falls ich da mal noch Namen einbauen mag.

            Wie kann ich das am besten und vorallem effizient umsetzten?

            Die folgenden Werte stehen in der Datenbank + Beispiel:
            id user_id sender_id type title text created is_read deleted
            1 5 1 info Titel Nachricht timestamp 0 0
            Ausgabe sollte dann in etwa wie folgt aussehen:

            Nachricht: xyz... wurde an 50 Benutzer gesendet -> Weitere Informationen
            Weitere Informationen:
            - Gesendet an Benutzer: 1,4,8,14,45,50,83...
            - Gelesen: 1,14,45,83...
            - Gelöscht: 14,83...

            Kommentar


            • #7
              Bei 'Gesendet an Benutzer' sehe ich jetzt nicht die Spalte hierfür in deinem Beispiel...

              Aber die Abfrage wer es gelesen hat:

              $sql = "SELECT `user_id` FROM `Nachricht` WHERE `is_read` = 1 AND `nachrichtID` = DieIDderNachricht";

              Damit sollten alle ausgelesen werden welche die betreffende Nachricht bekommen haben und auch gelesen haben (wg. AND-Operator). Da ich aber bereits öfter Posts von dir gelesen habe meine ich schon, dass du einen fortgeschrittenen Level hast und diese Zeile wohl zu simple erscheint. Denke mal eher das deine Problembeschreibung bei mir nicht voll ankam :-)
              ________
              Megabyte66
              ________

              Kommentar


              • #8
                Gesendet an Benutzer (Empfänger) ist die user_id.

                Ich versuche es nochmal zu erklären: Statt einen Log für jede Nachricht auszugeben, wenn die selbe Nachricht an z.B 50 Benutzer gesendet wurde, möchte ich das ganze in eine Ausgabe bündeln.
                Bei einer Nachricht an mehrere Benutzer ist [sender_id, Type, Title, Text(könnte sich in zukünftigen updates ändern)] & [created](fast kleine unterschiede im sekunden bereich) identisch.

                Die Ausgabe die entstehen soll, sollte in etwa wie folgt aussehen:
                Nachricht: "Dies ist eine Test Nachricht" wurde von SystemUser an 50 Benutzer gesendet -> Weitere Informationen(Öffnet ein modal mit weiteren Informationen).

                Die weiteren Informationen sollen dann die restlichen Daten zu allen einträgen enthalten.
                - Empfänger (User_id): 1,4,8,14,45,50,83...
                - Gelesen (is_read): 1,14,45,83...
                - Gelöscht (deleted): 14,83...

                Kurz gesagt ich mag alle Einträge die den selben Titel und Sender haben und innerhalb von 5 Minuten ab der ersten Nachricht erstellt wurden in einen Eintrag zusammen fassen.

                Beispiel:
                id user_id sender_id type title text created is_read deleted
                1 5 3 info Nachricht Titel Hallo 21.08.2021 14:05:39 1 1
                2 3 5 security Account Sicherheit Dein Account 25.09.2021 00:45:35 0 0
                3 2 1 info Test Nachricht Titel Nachricht Test 25.09.2021 00:45:42 0 0
                4 3 1 info Test Nachricht Titel Nachricht Test 25.09.2021 00:45:42 1 1
                5 4 1 info Test Nachricht Titel Nachricht Test 25.09.2021 00:45:43 1 0
                6 9 1 security Account Sicherheit Dein Account 25.09.2021 00:46:19 1 0
                Ausgabe sollte dann für die Zusammenfassung wie folgt lauten:
                Nachricht: "Test Nachricht Titel" wurde von "1(SystemUser)" an 3(Anzahl Empfänger) Benutzer gesendet -> Weitere Informationen
                - Empfänger (User_id): 2,3,4
                - Gelesen (is_read): 3,4
                - Gelöscht (deleted): 3

                Am besten die Weiteren Informationen als Array und das ganze dann irgendwie mit einer zuordnungs id, da es ja mehrere dieser fälle geben kann.

                Kommentar


                • #9
                  Ich würde das so aufziehen: Sortieren
                  1. nach sender_id
                  2. nach title
                  3. nach created
                  Dann hast Du die Nachrichten des Benutzers mit dem selben Titel jeweils aufeinander folgend im Resultset vorliegen.
                  Dann eine Schleife darüber und die Daten sammeln.

                  Kommentar


                  • #10
                    Grundsetztlich keine Schlechte idee, aber dann würde es mir die reihenfolge für die anderen Nachrichten durcheinander bringen.
                    Ich versuche es mal zu veranschaulichen, ich finde es immer sehr sehr schwer so etwas zu erklären.
                    Ich habe das ganze mal in form einer Tabelle ausgeben lassen.

                    So sieht es derzeit aus:
                    before.png

                    Und so sollte es am ende dann in etwa aussehen. (Bitte beachten, dass die Tabelle in umgekehrter reihenfolge ausgegeben wird. Aktuellere Einträge sind oben.)
                    after.png

                    Kommentar


                    • #11
                      Verstehe, die Reihenfolge der Nachrichten nach Sendezeit sollte erhalten bleiben. Das sollte sich machen lassen, wenn Du am Schluss wieder nach Zeit sortierst.

                      Kommentar


                      • #12
                        Hab es jetzt erst nach sender, dann nach titel und zum schluss nach created sortiert. So kommt es jetzt aus der Datenbank in den Array den ich dann veraberiten mag.
                        Wie stelle ich das ganze dann jetzt in dem foreach loop an?

                        Ich hatte jetzt versucht dass ganze mit variablen zum zwischenspeichern und mit if Abfragen zu lösen, das funktioniert aber überhaupt nicht. Der Count geht nicht hoch, also irgendwas passt da nicht.
                        Hier mein versuch (mit solchen zusammenpacken von mehreren Daten in einen Block und dann erst wiedergeben habe ich noch so meine Probleme):
                        PHP-Code:
                        <?php
                            $count 
                        0;
                            
                        $last_sender = -1;
                            
                        $last_type 0;
                            
                        $last_title 0;
                            foreach (
                        $data as $content) {
                                if(
                        $content->sender_id == $last_sender && $content->type == $last_type && $content->title == $last_title){
                                    if(
                        strtotime($content->created) > strtotime("-5 minutes")) {
                                        
                        $count++;
                                        
                        $userArray[] = $content->user_id;
                                        
                        $userRead[] = $content->is_read;
                                        break;
                                    }
                                }
                        ?>
                            <tr>
                                <td><?php echo $content->id?></td>
                                <td><?php echo $content->sender_id?></td>
                                <td><?php echo $content->user_id?></td>
                                <td>
                                    <?php
                                        
                        if($content->type == 'info'){
                                            echo 
                        '<h5><span class="badge badge-pill badge-info">Info</span></h5>';
                                        } else if(
                        $content->type == 'security'){
                                            echo 
                        '<h5><span class="badge badge-pill badge-danger">Sicherheit</span></h5>';
                                        } else {
                                            echo 
                        '<h5><span class="badge badge-pill badge-danger">Error</span></h5>';
                                        }
                                    
                        ?>  
                                </td>
                                <td><?php echo $content->title?></td>
                                <td><?php echo $content->text?></td>
                                <td>
                                    <?php
                                        $created_at 
                        strtotime($content->created);
                                        
                        $date date('d.m.Y'$created_at);
                                        
                        $time date('H:i'$created_at);
                                        echo 
                        $date ' um ' $time ' Uhr';
                                    
                        ?>
                                </td>
                                <td>
                                    <?php
                                        
                        if($content->is_read == 0){
                                            echo 
                        '<span style="color: red;"><i class="feather icon-x-circle"></i></span>';
                                        } else {
                                            echo 
                        '<span style="color: green;"><i class="feather icon-check-circle"></i></span>';
                                        }
                                    
                        ?>
                                </td>
                            </tr>
                        <?php
                                $last_sender 
                        $content->sender_id;
                                
                        $last_type $content->type;
                                
                        $last_title $content->title;
                                
                        $last_created $content->created;
                            }
                        ?>

                        Kommentar


                        • #13
                          Ich habe das so gemacht, dass ich die Daten, die zusammen gehören in einem Array $rec gesammelt habe. Unterscheiden sich Titel oder Sender oder ist der Zeitunterschied zu groß, beginne ich einen neuen Datensatz. Nicht allzu intensiv getestet aber das Ergebnis macht einen plausiblen Eindruck:
                          PHP-Code:
                          $sql "
                              SELECT `id`, `user_id`, `sender_id`, `type`, `title`,
                                  `created`, TO_SECONDS(created) AS secs, `is_read`, `deleted`
                              FROM `messages`
                              ORDER BY sender_id, title, secs"
                          ;
                          if (
                          $erg $conn->query($sql)) {
                              
                          $result = [];
                              
                          // Speichert die Sekunden des ersten Datensatzes:
                              
                          $secsStart 0;
                              
                          // Speichert die gesammelten Daten:
                              
                          $rec = ['sender_id' => '''title' => ''];
                              while (
                          $row $erg->fetch_assoc()) {
                                  
                          var_dump($row);
                                  
                          $sender_id $row['sender_id'];
                                  
                          $user_id $row['user_id'];
                                  
                          $title $row['title'];
                                  
                          $secs $row['secs'];
                                  
                          $is_read $row['is_read'];
                                  
                          $deleted $row['deleted'];
                                  
                          // In $rec legen wir jeweils den Datensatz für eine Nachricht an,
                                  // die mehrfach gesendet wurde:
                                  // Wenn mehr als 5 Sekunden seit dem Anlegen eines neuen Datensatzes
                                  // vergangen sind oder sich der Absender oder der Titel geändert hat,
                                  // müssen wir einen neuen Datensatz beginnen:
                                  
                          if ($secs $secsStart || $secs $secsStart 0
                                      
                          || $rec['sender_id'] != $sender_id || $rec['title'] != $title) {
                                      
                          $secsStart $secs;
                                      if (
                          $rec['sender_id'] != '') {
                                          
                          // Aktuellen Datensatz in $result eintragen:
                                          
                          $result[] = $rec;
                                          
                          // Neuen Datensatz beginnen:
                                          
                          $rec = ['sender_id' => '''title' => ''];
                                      }
                                  }
                                  
                          // Aktuelle Daten in Datensatz eintragen
                                  
                          $rec['secs'] = $secs;
                                  
                          $rec['sender_id'] = $sender_id;
                                  
                          $rec['title'] = $title;
                                  
                          $rec['user_id'][] = $user_id;
                                  if (
                          $is_read == '1') {
                                      
                          $rec['is_read'][] = $user_id;
                                  }
                                  if (
                          $deleted == '1') {
                                      
                          $rec['deleted'][] = $user_id;
                                  }
                              }
                              
                          var_dump($result);
                              
                          // Ergebnis nach Zeit sortieren:
                              
                          usort($result, function ($a$b) {return $a['secs'] - $b['secs'];});
                              
                          // Ergebnis ausgeben:
                              
                          foreach ($result as $item) {
                                  echo 
                          'Benutzer: ' $item['sender_id'] . '<br>';
                                  echo 
                          'Titel der Nachricht: ' $item['title'] . '<br>';
                                  echo 
                          'Empfänger: ' implode(','$item['user_id']) . '<br>';
                                  if (isset(
                          $item['is_read'])) {
                                      echo 
                          'Gelesen: ' implode(','$item['is_read']) . '<br>';
                                  }
                                  if (isset(
                          $item['deleted'])) {
                                      echo 
                          'Gelöscht: ' implode(','$item['deleted']) . '<br>';
                                  }
                              }
                          }
                          ?> 

                          Kommentar


                          • #14
                            Jetzt passt es fast. Das hat den größten Teil schonmal abgedeckt. Nun sind mir noch 2 Fehler aufgefallen. (Reihenfolge auf dem Bild Stimmt wegen der tabellen Sortierung nicht!)

                            1. Es Fehlen 2 Einträge von 13 werden 11 Angezeigt. [28,35] Fehlen
                            2. Werden falsche Nachrichten zusammen gepackt [7,8] sollten einzeln angezeigt werden. Kann man da noch auf gleiche User_id prüfen?
                            Wenn die gleich ist dann einfach einzeln ausgeben. (Sowas sollte im normalfall nicht vorkommen, aber dann hab ich das auch abgedeckt)

                            Ich habe mal meine Test Daten hier per SQL Dump ausgegeben: https://pastebin.com/hf6Cj8Cx

                            Und nochmal die Aktuelle Ausgabe als Tabellen Version:
                            Screenshot 2021-09-26 at 14-01-41 Story V - Nachricht.png

                            Kommentar


                            • #15
                              Das Problem mit den fehlenden Einträgen liegt daran, dass ich vergessen habe, nach der Schleife den letzten Eintrag dem Ergebnis hinzu zu fügen:
                              PHP-Code:
                              $sql "
                                  SELECT `id`, `user_id`, `sender_id`, `type`, `title`,
                                      `created`, TO_SECONDS(created) AS secs, `is_read`, `deleted`
                                  FROM `messages`
                                  ORDER BY sender_id, title, secs"
                              ;
                              if (
                              $erg $conn->query($sql)) {
                                  
                              $result = [];
                                  
                              // Speichert die Sekunden des ersten Datensatzes:
                                  
                              $secsStart 0;
                                  
                              // Speichert die gesammelten Daten:
                                  
                              $rec = ['sender_id' => '''title' => ''];
                                  while (
                              $row $erg->fetch_assoc()) {
                                      
                              var_dump($row);
                                      
                              $sender_id $row['sender_id'];
                                      
                              $user_id $row['user_id'];
                                      
                              $title $row['title'];
                                      
                              $secs $row['secs'];
                                      
                              $is_read $row['is_read'];
                                      
                              $deleted $row['deleted'];
                                      
                              // In $rec legen wir jeweils den Datensatz für eine Nachricht an,
                                      // die mehrfach gesendet wurde:
                                      // Wenn mehr als 5 Sekunden seit dem Anlegen eines neuen Datensatzes
                                      // vergangen sind oder sich der Absender oder der Titel geändert hat,
                                      // müssen wir einen neuen Datensatz beginnen:
                                      
                              if ($secs $secsStart || $secs $secsStart 0
                                          
                              || $rec['sender_id'] != $sender_id || $rec['title'] != $title) {
                                          
                              $secsStart $secs;
                                          if (
                              $rec['sender_id'] != '') {
                                              
                              // Aktuellen Datensatz in $result eintragen:
                                              
                              $result[] = $rec;
                                              
                              // Neuen Datensatz beginnen:
                                              
                              $rec = ['sender_id' => '''title' => ''];
                                          }
                                      }
                                      
                              // Aktuelle Daten in Datensatz eintragen
                                      
                              $rec['secs'] = $secs;
                                      
                              $rec['sender_id'] = $sender_id;
                                      
                              $rec['title'] = $title;
                                      
                              $rec['user_id'][] = $user_id;
                                      if (
                              $is_read == '1') {
                                          
                              $rec['is_read'][] = $user_id;
                                      }
                                      if (
                              $deleted == '1') {
                                          
                              $rec['deleted'][] = $user_id;
                                      }
                                  }
                                  
                              $result[] = $rec;
                                  
                              var_dump($result); 
                              (vorletzte Zeile)
                              Das andere Problem muss ich mir genauer ansehen.

                              Kommentar

                              homepage-forum.de - Hilfe für Webmaster! Statistiken

                              Einklappen

                              Themen: 56.938   Beiträge: 431.246   Mitglieder: 28.750   Aktive Mitglieder: 81
                              Willkommen an unser neuestes Mitglied, Herman.

                              Online-Benutzer

                              Einklappen

                              225 Benutzer sind jetzt online. Registrierte Benutzer: 5, Gäste: 220.

                              Mit 3.502 Benutzern waren am 23.01.2020 um 17:20 die meisten Benutzer gleichzeitig online.

                              Die neuesten Themen

                              Einklappen

                              Die neuesten Beiträge

                              Einklappen

                              Lädt...
                              X