Sven: MySQL: Eintrag suchen, der die größte Übereinstimmung hat?

Hallo zusammen,

gibt es eine Möglichkeit mit MySQL so suchen zu lassen, dass ich den Eintrag erhalte, der mit dem Such-String die größtmögliche Übereinstimmung hat?

Beispielsweise stehen in der Tabelle 2 Einträge:
Pfannkuchen
Nudelholz

Und ich suche nach 'Pfanne' - dann sollte er mir Pfannkuchen rausschmeißen *g*

Klingt blöd - ist auch blöd. Aber vielleicht gibts da ne Möglichkeit?

Vielen Dank!

Lg
Sven

  1. Klingt blöd - ist auch blöd. Aber vielleicht gibts da ne Möglichkeit?

    ich erweitere deine liste mal:
    pfannkuchen
    pfannenstiel
    annegreth
    nudelholz

    feld like '%pfanne%' wird dir da leider auch nicht helfen

    dir bleibt nur übrigen den suchbegriff zu zerteilen, shingles nennen sich diese dinger - also satz oder wortbestandteile

    sprich aus pfanne suchbegriff machst trennst du alle möglichen substrings raus, die aus 3 zeichen bestehen

    pfa fan ann nne

    feld like '%pfanne%'
    wenn das keine ergebnisse liefert, dann nimmst du die wortteile:

    feld like '%pfa%'
    feld like '%fan%'
    feld like '%ann%'
    feld like '%nne%'

    damit hast du eine 100%ig übereinstimmung bei pfannenstiel, 3 treffer bei pfannkuchen und 2 bei annegreth

    1. sprich aus pfanne suchbegriff machst trennst du alle möglichen substrings raus, die aus 3 zeichen bestehen

      pfa fan ann nne

      feld like '%pfanne%'
      wenn das keine ergebnisse liefert, dann nimmst du die wortteile:

      feld like '%pfa%'
      feld like '%fan%'
      feld like '%ann%'
      feld like '%nne%'

      damit hast du eine 100%ig übereinstimmung bei pfannenstiel, 3 treffer bei pfannkuchen und 2 bei annegreth

      Hey, vielen Dank, das klingt schonmal ziemlich genial. Hab auch soweit meine Funktion gemacht, die mir die Strings unterteilt, nur bei der Abfrage bin ich mir jetzt nicht sicher:

      Muss ich da für jeden Fall eine Abfrage starten, oder lässt sich das kombinieren? Falls ich in deinem Beispiel 4 Abfragen benötige, muss es doch eine Möglichkeit geben, die miteinander zu vergleichen, oder?

      Lg
      Sven

      1. Muss ich da für jeden Fall eine Abfrage starten, oder lässt sich das kombinieren? Falls ich in deinem Beispiel 4 Abfragen benötige, muss es doch eine Möglichkeit geben, die miteinander zu vergleichen, oder?

        abfragen zusammenfügen tust du mit UNION

        1. Hallo,

          abfragen zusammenfügen tust du mit UNION

          Ja, das habe ich auch so gemacht... wobei ich die jetzt zum testen einfach hintereinander geschrieben habe:

          (SELECT name FROM test.test WHERE name LIKE '%pfa%')
          UNION
          (SELECT name FROM test.test WHERE name LIKE '%fan%')
          UNION
          (SELECT name FROM test.test WHERE name LIKE '%ann%')
          UNION
          (SELECT name FROM test.test WHERE name LIKE '%nne%')
          ORDER BY name

          Aber es muss doch eine Möglichkeit geben, die Suchtreffer dann zu sortieren? Aus der Ergebnistabelle geht ja nicht hervor, welcher Eintrag nun die meisten Treffer hatte...?

          Lg
          Sven

        2. Hallo,

          ich habs geschafft - die Funktion tut das, was sie tun soll. Aber das sind seeehr viele Schleifen... ich kopiere mal den Code hier rein, vielleicht mag ihn ja mal jemand überfliegen. Falls das zu verwirrend ist, und niemand Lust hat, sich das anzusehen, kann ich das voll verstehen - ich bin sicher, es geht auch einfacher.

          Vielleicht hat ja jemand eine Optimierungsidee?

          Lg
          Sven

          if($_POST['search']) {
            $search_string = strip_tags($_POST['search']);

          // Länge des Strings ermitteln, wenn nötig auf 20 Zeichen begrenzen
            $search_len = strlen($search_string);
            if($search_len > 20) { $search_len = 20; }

          // Prüfen ob Suchstring zu kurz
            if($search_len < 3) {
              $error[] = $error_tooshort;
            }

          // Nur weitermachen, falls keine Fehler vorliegen
            if(count($error) == 0)
            {
              // String in Abschnitte unterteilen und in $search_substr[] speichern
              for($i=0; $i < $search_len; $i++)
              {
                if(strlen(substr($search_string,$i,3)) >= 3)
                {
                  $search_substr[] = substr($search_string,$i,3);
                }
              }

          // UNION-Abfrage erzeugen
              $sql = "";
              for($i=0; $i<count($search_substr); $i++)
              {
                $sql .= "(SELECT name
                    FROM datenbank.test
                    WHERE name
                    LIKE '%".$search_substr[$i]."%')";
                if($i < count($search_substr)-1) {
                  $sql .= " UNION ";
                } else {
                  $sql .= " LIMIT 10";
                }
              }

          // Abfrage durchführen: Für jeden Eintrag in der
              // Datenbank wird geprüft, welche Teilstrings
              // in den Eintrag hinein passen

          $result = mysql_query($sql);
              $num = mysql_num_rows($result);
              if($num > 0)
              {
                while($row = mysql_fetch_array($result))
                {
                  $j = 0;
                  for($i=0; $i<count($search_substr); $i++)
                  {
                    if(substr_count($row['name'],$search_substr[$i]) > 0)
                    {
                      $j++;
                    }
                  }
                  // In diesem zweidimensionalen Array werden
                  // gespeichert: Die Anzahl der Treffer und
                  // der dazugehörige Datenbank-Eintrag

          $search_res[] = array($j,$row['name']);
                }
              } else
              {
                $error[] = $error_noresults;
              }

          // Array sortieren
              rsort($search_res);

          // Array ausgeben
              for($i=0; $i<count($search_res); $i++)
              {
                for($j=0; $j<count($search_res[$i]); $j++)
                {
                  echo $search_res[$i][$j];
                }
              }
            }
          }