tutorials.de Buch-Aktion 05/2012
Like Tree4Danke
  • 1 Beitrag von einfach nur crack
  • 1 Beitrag von Yaslaw
  • 1 Beitrag von einfach nur crack
  • 1 Beitrag von saftmeister
ERLEDIGT
JA
ANTWORTEN
13
ZUGRIFFE
311
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    Thomasio Thomasio ist offline Mitglied Platin
    Registriert seit
    Aug 2006
    Beiträge
    685
    Ich suche die schnellste Möglichkeit aus MySql einen Datensatz zu laden, aber nur, wenn es nur genau einen passenden Datensatz gibt.

    Meine umständliche Version sieht so aus:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    $abfrage = mysql_query("SELECT * FROM `tabelle` WHERE `feld1` = 'irgendwas' AND `feld2` = 'sonstwas'");
    while($row = mysql_fetch_object($abfrage))
    {
         $datensaetze[] = $row;
    }
     
    if(count($datensaetze) < 1)
    {
         // nicht gefunden
    }
     
    if(count($datensaetze) > 1)
    {
         // mehrere gefunden
    }
     
    if(count($datensaetze) == 1)
    {
         $ergebnis = $datensaetze[0];
    }

    Wie mache ich das besser?
     

  2. #2
    Avatar von einfach nur crack
    einfach nur crack einfach nur crack ist offline mag Cookies & Kekse
    tutorials.de Premium-User
    Registriert seit
    May 2007
    Ort
    Dresden (Sachsen)
    Beiträge
    1.961
    Du kannst da mit HAVING und GROUP BY arbeiten:
    Code SQL:
    1
    
    SELECT *, COUNT(`feld1`) FROM `tabelle` WHERE `feld1` = 'irgendwas' AND `feld2` = 'sonstwas' GROUP BY `feld1` HAVING COUNT(`feld1`) = 1
    Thomasio bedankt sich. 
    Ich mag:
    • positive Bewertungen meiner Beiträge
    • ein Danke für meine hilfreichen Beiträge

    Dabei kann ich dir helfen: PHP --- Javascript --- Ruby --- Coffeescript --- CSS --- HTML --- Webtechnologien --- Shell --- UNIX

    ... noch was: falls du mit dem Thema hier fertig bist, dann kannst du es auch als erledigt markieren.

  3. #3
    Thomasio Thomasio ist offline Mitglied Platin
    Registriert seit
    Aug 2006
    Beiträge
    685
    Werde ich gleich ausprobieren, danke.
     

  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
    Das * ist ganz unschön und gefährlich bei einem GROUP BY

    MySQL ist da etwas unseriös, da du nicht alle Felder im GROUP BY definieren musst, die Gruppiert werden. Mit dem * im SELECT gruppiert er alles was nicht mit einer Guppierungsfunktion versehen ist (Also SUM(), COUNT(), MAX() etc)

    Nemen wir mal diese Tabelle
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    
    my_table:
    id | feld1 | feld2 | feld13
    ---------------------------
     1 | A     | v     | 111
     2 | A     | v     | 222
     3 | B     | x     | 333
     4 | C     | y     | 444
     5 | C     | z     | 444
    Wenn man jetzt ein GROUP BY feld1 macht und dabei ein * im SELECT hat, wird trotzdem nach allen Feldern Gruppiert. Ergo wird COUNT() immer 1 ausagebn, da die id und das feld3 immer unterschiedlich ist.

    Interessiert uns nur das feld1, dann kann man das simple machen, fast so wie crack gezeigt hat. Einfach den * entfernen

    Das folgende Query gibt nix aus, da die Kombnation A/z 2 mal vorkommt.
    Code sql:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
     SELECT
        feld1
     FROM
        my_table
     WHERE
        feld1 = 'A'
        AND feld2 = 'v'
     GROUP BY
        feld1
     HAVING
        COUNT(*) = 1;
    Wird der Filter hingegen auf C/y gesetzt, dann wird auch 'C' ausgegeben, da diese Kombination nur einmal vorkommt.

    Will man nun aber alle Felder von der Tabelle haben, dann kann man sie zurückverknüpfen
    Code sql:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    SELECT
        my_data.*
    FROM
        my_table AS my_data
        INNER JOIN (
                SELECT
                    feld1
                FROM
                    my_table
                WHERE
                    feld1 = 'A'
                    AND feld2 = 'v'
                GROUP BY
                    feld1
                HAVING
                    COUNT(*) = 1
            ) AS FILTER
            ON my_data.feld1 = FILTER.feld1
            AND my_data.fedl2 = FILTER.feld2;

    Wobei es auch hier besser wäre, den * durch eine Felderliste zu ersetzen.

    Wenn du das ganze noch lesbar im PHP habe willst, dann empfehle ich die folgenden 2 Punkte
    a) den SQL-Teil in PHP formatieren: Heredoc-Syntax
    b) Die Complex (Curly) Syntax anwenden um die Strings zusammenzusetzen. Das reduziert das Chaos mit öffnenden und schliessenden Anführungszeichen und den Verbindungs-Punkten

    PHP-Code:
    $feld1 'C';
    $feld2 'y';

    $sql = <<<SQL
    SELECT
        my_data.*
    FROM
        my_table AS my_data
        INNER JOIN (
                SELECT
                    feld1
                FROM
                    my_table
                WHERE
                    feld1 = '
    {$feld1}'
                    AND feld2 = '
    $feld2'
                GROUP BY
                    feld1
                HAVING
                    COUNT(*) = 1
            ) AS filter
            ON my_data.feld1 = filter.feld1
            AND my_data.fedl2 = filter.feld2;
    SQL;

    $result mysql_query($sql); 
    Lime bedankt sich. 
    ---------------------------------------------------------------------------------------------------
    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
    Thomasio Thomasio ist offline Mitglied Platin
    Registriert seit
    Aug 2006
    Beiträge
    685
    Irgendwie hilft mir das nicht wirklich.
    Ich will gar nicht alle einmaligen Datensätze haben, ich will nur dann genau einen Datensatz laden, wenn es wirklich nur einen passenden Datensatz gibt.
    Wenn nicht, will ich wissen, ob es gar keinen oder mehr als einen gab, aber in dem Fall brauche ich die Daten daraus nicht.
    Meine Lösung dazu funktioniert schon, ich fand sie nur recht umständlich, weil ich immer alle Datensätze laden muss und dann mit 3 if checken, was zutrifft.
     

  6. #6
    Avatar von saftmeister
    saftmeister saftmeister ist gerade online Der Saft sei mit dir
    tutorials.de Premium-User
    Registriert seit
    May 2006
    Ort
    There is no place like 127.0.0.1
    Beiträge
    3.521
    Du könntest die Funktion COUNT() verwenden.
     
    Grüße
    --
    Qualität des Codes wird in WTF's/Min gemessen: Je mehr, desto schlechter der Code ;-)

  7. #7
    Thomasio Thomasio ist offline Mitglied Platin
    Registriert seit
    Aug 2006
    Beiträge
    685
    Klar, aber kann ich COUNT() mit LIMIT 0,1 kombinieren?
    Und dann muss ich immer noch 3 if drunter machen.
     

  8. #8
    Avatar von saftmeister
    saftmeister saftmeister ist gerade online Der Saft sei mit dir
    tutorials.de Premium-User
    Registriert seit
    May 2006
    Ort
    There is no place like 127.0.0.1
    Beiträge
    3.521
    Nein, du kannst IMHO COUNT() nicht mit Limit zusammen verwenden. Aber du kannst deinen Code so aufbauen, das er, wenn COUNT() größer 0 zurück liefert, trotzdem nur den ersten Datensatz abholt. Oder habe ich da jetzt was falsch verstanden?
     
    Grüße
    --
    Qualität des Codes wird in WTF's/Min gemessen: Je mehr, desto schlechter der Code ;-)

  9. #9
    Avatar von einfach nur crack
    einfach nur crack einfach nur crack ist offline mag Cookies & Kekse
    tutorials.de Premium-User
    Registriert seit
    May 2007
    Ort
    Dresden (Sachsen)
    Beiträge
    1.961
    Du kannst diese Abfrage aber verschachteln und als Datenmenge nutzen, auf der dann eine weiter Abfrage aufbaut, die dann LIMIT nutzt.
     
    Ich mag:
    • positive Bewertungen meiner Beiträge
    • ein Danke für meine hilfreichen Beiträge

    Dabei kann ich dir helfen: PHP --- Javascript --- Ruby --- Coffeescript --- CSS --- HTML --- Webtechnologien --- Shell --- UNIX

    ... noch was: falls du mit dem Thema hier fertig bist, dann kannst du es auch als erledigt markieren.

  10. #10
    Avatar von saftmeister
    saftmeister saftmeister ist gerade online Der Saft sei mit dir
    tutorials.de Premium-User
    Registriert seit
    May 2006
    Ort
    There is no place like 127.0.0.1
    Beiträge
    3.521
    Also COUNT() liefert immer genau einen Datensatz zurück. Du kannst es machen, genau wie einfach nur crack im Post #2 schon vorgeschlagen hat, nur ohne HAVING und GROUP BY, denn es kommt ohnehin nur ein Datensatz zurück. Den liest du mit mysql_fetch_array() oder einer anderen Fetch-Funktion aus, hast den ersten gewünschten Datensatz zusammen mit der Anzahl der Datensätze, die sonst noch nach diesem Kriterien gefunden wurden.

    Das ist doch das, was du erreichen willst, oder?
     
    Grüße
    --
    Qualität des Codes wird in WTF's/Min gemessen: Je mehr, desto schlechter der Code ;-)

  11. #11
    Thomasio Thomasio ist offline Mitglied Platin
    Registriert seit
    Aug 2006
    Beiträge
    685
    Ich habe schon begriffen was ihr meint, aber wenn immer nur ein Datensatz zurückkommt, weiss ich im Fehlerfall nicht, ob es gar keinen oder mehr als einen gab, weil auch dann wenn es zwei gab nichts zurück kommt.
    Selbst wenn er mir eine Zahl ausspuckt, wieviele es gab, dann muss ich die immer noch mit 3 if prüfen.
    Oder habe ich den Trick übersehen?
     

  12. #12
    Avatar von einfach nur crack
    einfach nur crack einfach nur crack ist offline mag Cookies & Kekse
    tutorials.de Premium-User
    Registriert seit
    May 2007
    Ort
    Dresden (Sachsen)
    Beiträge
    1.961
    Du fügst einfach eine zusätzliche Spalte an, die dann die Anzahl der gefundenen Datensätze enthält. Und wenn kein Datensatz gefunden wurde, dann erhältst du auch keine Daten von der Datenbank.
    Thomasio bedankt sich. 
    Ich mag:
    • positive Bewertungen meiner Beiträge
    • ein Danke für meine hilfreichen Beiträge

    Dabei kann ich dir helfen: PHP --- Javascript --- Ruby --- Coffeescript --- CSS --- HTML --- Webtechnologien --- Shell --- UNIX

    ... noch was: falls du mit dem Thema hier fertig bist, dann kannst du es auch als erledigt markieren.

  13. #13
    Avatar von saftmeister
    saftmeister saftmeister ist gerade online Der Saft sei mit dir
    tutorials.de Premium-User
    Registriert seit
    May 2006
    Ort
    There is no place like 127.0.0.1
    Beiträge
    3.521
    Zitat Zitat von Thomasio Beitrag anzeigen
    Ich habe schon begriffen was ihr meint, aber wenn immer nur ein Datensatz zurückkommt, weiss ich im Fehlerfall nicht, ob es gar keinen oder mehr als einen gab, weil auch dann wenn es zwei gab nichts zurück kommt.
    Selbst wenn er mir eine Zahl ausspuckt, wieviele es gab, dann muss ich die immer noch mit 3 if prüfen.
    Oder habe ich den Trick übersehen?
    Du brauchst keine 3 if-Abfragen. Genau genommen, brauchst du nur eine und einen Else-Zweig:

    Code php:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
    $abfrage = mysql_query("SELECT *, COUNT(*) AS anzahl FROM `tabelle` WHERE `feld1` = 'irgendwas' AND `feld2` = 'sonstwas'") or die( mysql_error() );
     
    $datensatz = mysql_fetch_array( $abfrage );
     
    if($datensatz['anzahl'] > 0)
    {
      // Mindestens einen gefunden
     
      echo $datensatz['irgend_eine_spalte'];
      
      // Wenn du noch genauer prüfen willst, kannst du hier drinnen
      if( $datensatz['anzahl'] > 1 )
      {
        // Mindestens zwei
        echo "Hab noch " . $datensatz['anzahl'] - 1 . ' weitere Datensätze gefunden'; // -1 weil wir den ersten ja schon ausgegeben haben.
      }
    }
    else
    {
      // Kein Datensatz gefunden
    }
    Thomasio bedankt sich. 
    Grüße
    --
    Qualität des Codes wird in WTF's/Min gemessen: Je mehr, desto schlechter der Code ;-)

  14. #14
    Thomasio Thomasio ist offline Mitglied Platin
    Registriert seit
    Aug 2006
    Beiträge
    685
    Ahhh, jetzt habe sogar ich es begriffen.
    Vielen Dank euch allen.
     

Ähnliche Themen

  1. Prüfen, ob Eintrag vorhanden ist
    Von lisali im Forum PHP
    Antworten: 11
    Letzter Beitrag: 16.06.10, 14:30
  2. Antworten: 10
    Letzter Beitrag: 16.05.10, 19:12
  3. Prüfen, ob Eintrag in DB steht
    Von Godstyle im Forum PHP
    Antworten: 15
    Letzter Beitrag: 31.01.10, 04:51
  4. SQL Eintrag prüfen
    Von Duellking im Forum Relationale Datenbanksysteme
    Antworten: 1
    Letzter Beitrag: 21.12.08, 21:28
  5. MySQL: Daten vor Eintrag prüfen
    Von DanielBodensee im Forum PHP
    Antworten: 7
    Letzter Beitrag: 18.04.06, 09:16