Tabellenspalten "zusammenziehen"?
Tabellenspalten "zusammenziehen"?
am 16.05.2006 02:52:36 von Sebastian Gohres
Hi!
Hab da mal eine Frage:
Ich versuche gerade eine Personensuche zu erstellen, soweit auch keine
Probleme. Nur habe ich ein Problem. Meine Tabelle enthält getrennte
Spalten für die Adresse oder den Namen, z. B.:
| id | vorname | nachname | strasse | hausnummer |
| 1 | Hans Werner | Meier | Dorfstrasse | 13a |
Angenommen, nun wird nach dem Name "Meier" gesucht, sieht es momentan
wie folgt aus:
select id from personen where vorname like '%Meier%' or nachname like
'%Meier%'
Was aber, wenn ich z. B. "Werner Meier" eingebe?
select id from personen where vorname like '%Werner Meier%' or nachname
like '%Werner Meier%'
Findet mySQL natürlich nicht, wie auch.
Gibt es da eine Möglichkeit, wie ich z. B. vorname und nachname
zusammenziehe und dann suche?
MfG
S. Gohres
Re: Tabellenspalten "zusammenziehen"?
am 16.05.2006 04:32:56 von Niels Braczek
Sebastian Gohres schrieb:
> Findet mySQL natürlich nicht, wie auch.
> Gibt es da eine Möglichkeit, wie ich z. B. vorname und nachname=20
> zusammenziehe und dann suche?
Trenne die Eingaben. Biete ein Suchfeld für Vornamen und Nachnamen an,
nicht nur für Namen. Das vereinfacht die Programmierung und erhöht di=
e
Usability.
MfG
Niels
--=20
| http://www.kolleg.de =B7 Das Portal der Kollegs in Deutschland |
| http://www.bsds.de =B7 BSDS Braczek Software- und DatenSysteme |
| Webdesign =B7 Webhosting =B7 e-Commerce =B7 Joomla! Content Management =
|
------------------------------------------------------------ ------
Re: Tabellenspalten "zusammenziehen"?
am 16.05.2006 07:18:51 von Thomas Rachel
Sebastian Gohres wrote:
> Findet mySQL natürlich nicht, wie auch.
> Gibt es da eine Möglichkeit, wie ich z. B. vorname und nachname
> zusammenziehe und dann suche?
Alternative zu Niels' Version:
select id from personen where concat(vorname,' ',nachname)
like '%Werner Meier%'
unter der Annahme allerdings, daà auch in der Reihenfolge gesucht wird.
Ansonsten ergänze: ... or (nachname,' ',vorname) like '%Werner Meier%'
Hat - genau wie auch Deine Version den groÃen Nachteil, daà keine Indizes
verwendet werden können und daà genau ein Leerzeichen angegeben sein
muÃ.
Das nette Manual unter dev.mysql.com verrät Dir aber auch gerne, wie
Volltextindizes und -suche funktionieren - die kommen mir hier
geeigneter vor (kann mich aber auch irren...)
HTH,
Thomas
--
while(!asleep()) sheep++;
Re: Tabellenspalten "zusammenziehen"?
am 16.05.2006 09:15:27 von Alex Hepp
Sebastian Gohres schrieb:
> Gibt es da eine Möglichkeit, wie ich z. B. vorname und nachname
> zusammenziehe und dann suche?
Die Frage ist wohl, was Du Deinem "Suchenden" anbieten möchtest.
1. Es soll genau nach dem Suchbegriff gesucht werden, das bedeutet, dass
es genau richtig ist, dass "Werner Meier" kein Ergebnis liefert.
2. Es soll möglich sein, nach Vor und Nachname zu suchen, dann wären 2
Felder, wie Niels bereits erwähnte, die richtige Lösung.
3. Biete eine komplette Suche an, die entweder als ODER-Suche, oder als
UND-Suche funktioniert, was bedeutet, dass Du einzelne Tokens (in diesem
Fall Suchbegriffe) herausziehst (bei php zb. mit split()) und dann nur
datensätze zurückgibst, die
a.) in einem der suchfelder eines der Begriffe enthält.
b.) alle Suchbegriffe in einem der Suchfelder vorkommen
a.) select id from personen where vorname like '%Meier%' or nachname
like '%Meier%' or vorname like '%Werner%' or nachname like '%Werner%';
b.) select id from personen where vorname like '%Meier%' and nachname
like '%Werner%' or vorname like '%Werner%' and nachname like '%Meier%';
Die letzte Version ist vereinfacht dargestellt. sollten es mehrere
Suchspalten geben, muss hier optimiert werden.
b.) select id from personen where (vorname like '%Meier%' or nachname
like '%Meier%' or beschreibung like '%Meier%') and (vorname like
'%Werner%' or nachname like '%Werner%' or beschreibung like '%Meier%')
[and (...wie oben mit weiteren Suchbegriffen)];
HTH...
Alex
Re: Tabellenspalten "zusammenziehen"?
am 17.05.2006 09:57:44 von christoph.soellner
//Trenne Deinen Suchstring nach Leerzeichen:
$lookfor_array = explode(" ", $_GET['myseachfield']);
//SQL vorbereiten
$sqlwhere = "WHERE (1=2)";
//Jedes Item durchsuchen.
foreach ($lookfor_array as $item) {
//collation-safe Suchstring
$sqlwhere .= " OR (UPPERCASE(vorname) LIKE UPPERCASE('%".
mysql_escape_string(item) ."%')";
$sqlwhere .= " OR (UPPERCASE(nachname) LIKE UPPERCASE('%".
mysql_escape_string(item) ."%')";
}
//Abfragen
$r= mysql_query("SELECT * FROM mytable ". $sqlwhere);
hth,
Christoph
Re: Tabellenspalten "zusammenziehen"?
am 17.05.2006 12:03:00 von Alex Hepp
Christoph Söllner schrieb:
> //Trenne Deinen Suchstring nach Leerzeichen:
> $lookfor_array = explode(" ", $_GET['myseachfield']);
>
> //SQL vorbereiten
> $sqlwhere = "WHERE (1=2)";
Im AND-Fall (um die AND Suche zu stricken) muss hier "WHERE 1" angegeben
werden...
> //Jedes Item durchsuchen.
> foreach ($lookfor_array as $item) {
> //collation-safe Suchstring
> $sqlwhere .= " OR (UPPERCASE(vorname) LIKE UPPERCASE('%".
> mysql_escape_string(item) ."%')";
> $sqlwhere .= " OR (UPPERCASE(nachname) LIKE UPPERCASE('%".
> mysql_escape_string(item) ."%')";
> }
Vielleicht solltest Du noch eine checkbox anbieten für CaseInsensitive
suche.. Bei Anklicken baust Du tatsächlich mit UPPERCASE zusammen. Im
anderen Fall musst Du das dann eben weglassen.
grüße
Alex
Re: Tabellenspalten "zusammenziehen"?
am 17.05.2006 12:28:06 von Kai Ruhnau
Christoph Söllner wrote:
> //Trenne Deinen Suchstring nach Leerzeichen:
> $lookfor_array = explode(" ", $_GET['myseachfield']);
>
> //SQL vorbereiten
> $sqlwhere = "WHERE (1=2)";
$sqlwhere=array();
> //Jedes Item durchsuchen.
> foreach ($lookfor_array as $item) {
> //collation-safe Suchstring
> $sqlwhere .= " OR (UPPERCASE(vorname) LIKE UPPERCASE('%".
> mysql_escape_string(item) ."%')";
$sqlwhere[]="vorname LIKE '%".mysql_real_escape_string($item)."%'
COLLATE ...._ci";
mysql_escape_string ist schon so lange Zeit deprecated...
Collations sind genau dafür da, Vergleiche caseinsensitive zu machen.
Üblicherweise setzt man für Namensspalten direkt eine caseinsensitive
Collation, dann kann man sich in der Bedingung den Nachsatz auch noch
sparen (s.u.)
> $sqlwhere .= " OR (UPPERCASE(nachname) LIKE UPPERCASE('%".
> mysql_escape_string(item) ."%')";
> }
$sqlwhere[]="nachname LIKE '%".mysql_real_escape_string($item).%'";
> //Abfragen
> $r= mysql_query("SELECT * FROM mytable ". $sqlwhere);
$r=mysql_query("SELECT * FROM mytable WHERE ".implode(" OR ",$sqlwhere));
Grüße
Kai
--
This signature is left as an exercise for the reader.
Re: Tabellenspalten "zusammenziehen"?
am 17.05.2006 12:49:54 von Alex Hepp
Kai Ruhnau schrieb:
> $sqlwhere[]="nachname LIKE '%".mysql_real_escape_string($item).%'";
was ich noch vergass: Aus Performancegründen würde ich natürlich bereits
im PHP eine neue Variable anlegen, die den String escaped enthält, und
diese dann hier verwenden.
Re: Tabellenspalten "zusammenziehen"?
am 17.05.2006 13:00:50 von Alex Hepp
Alex Hepp schrieb:
> Kai Ruhnau schrieb:
>> $sqlwhere[]="nachname LIKE '%".mysql_real_escape_string($item).%'";
>
> was ich noch vergass: Aus Performancegründen würde ich natürlich bereits
> im PHP eine neue Variable anlegen, die den String escaped enthält, und
> diese dann hier verwenden.
ohweh, entschuldigt den doppelpost... da habe ich doch glatt impliziert,
dass php benutzt wird...
das sollte natürlich angepasst werden ;) und wenn es keine sprache im
hintergrund gibt, und nur um die abfrage per mySQL geht, fällt das eben
flach...
Re: Tabellenspalten "zusammenziehen"?
am 18.05.2006 10:30:30 von christoph.soellner
> mysql_escape_string ist schon so lange Zeit deprecated...
Mea Culpa...
> Collations sind genau dafür da, Vergleiche caseinsensitive zu machen.
> Üblicherweise setzt man für Namensspalten direkt eine caseinsensitive
> Collation, dann kann man sich in der Bedingung den Nachsatz auch noch
> sparen (s.u.)
Gut, man nehme UTF8.
Kollation: utf8_general: Bullshit, da ue (Dt. Umlaut) = u.
Kollation: utf8_binary: Besser, aber Gross/klein wird beachtet,
was eben UPPERCASE() erforderlich macht.
Fazit: Kollationen sind delikat.
> $r=mysql_query("SELECT * FROM mytable WHERE ".implode(" OR ",$sqlwhere));
Nun gut, das ist jawohl Kosmetik...
Christoph
Re: Tabellenspalten "zusammenziehen"?
am 18.05.2006 23:59:26 von Thomas Rachel
Alex Hepp wrote:
>> was ich noch vergass: Aus Performancegründen würde ich natürlich
>> bereits im PHP eine neue Variable anlegen, die den String escaped
>> enthält, und diese dann hier verwenden.
>
> ohweh, entschuldigt den doppelpost... da habe ich doch glatt
> impliziert, dass php benutzt wird...
sowas... und das bei dieser NG?
SCNR
Thomas
Re: Tabellenspalten "zusammenziehen"?
am 19.05.2006 09:39:13 von Alex Hepp
Thomas Rachel schrieb:
> sowas... und das bei dieser NG?
öööh, auch das hatte ich mal wieder nicht beachtet(hab thunderbird
gesagt, er soll mir bitte nur abkürzungen der NG-Namen anzeigen)...
entschuldigt, aber zumindest wurde es weder explizit erwähnt, noch war
es vom OP her ersichtlich ;)
> SCNR
Hätte ich wohl auch nicht ;)
grüÃe Alex