Einträge über ein Feld mit Array Inhalt finden

Einträge über ein Feld mit Array Inhalt finden

am 26.06.2007 00:27:19 von Eric Hochreiter

Leider machen sich bei folgendem Problem bei mir noch meine
Wissenslücken bemerkbar...

Ich habe eine MySQL Tabelle mit einem Feld, dass durch Kommas getrennt
verschiedene Inhalte hat (z.B. "1,9,3,41,7,23,63").

Mein Problem ist nun, dass ich nicht weiß wie ich nun per SELECT
Einträge finden kann, bei denen ich nach einem Wert (z.B. "3") in
besagtem Feld suchen muss.

Also wenn das meine Tabelle ist:

A B C
1 ABC DEF 5,11,4,23,64,12
2 HGE KEO 1,9,3,41,7,23,63
3 OEA EWQ 8,32,4,3

will ich alle Einträge, die in Spalte C die "3" beinhalten, das wäre
also Zeile 2 und 3.

Wie muss ich das nun als SELECT WHERE Abfrage umsetzen? Da ich nicht
weiß, nach was ich überhaupt suchen muss, um eine Lösung dafür zu
finden, bin ich weder mit Google noch direkt im MySQL Manuell fündig
geworden und bevor ich mich hier tot suche, frage ich nebenher halt doch
lieber mal hier.

Gruß
Eric

--
www.TheNGA.de - Nintendo Gaming Agency

Re: Einträge über ein Feld mit Array Inhalt finden

am 26.06.2007 00:52:32 von Dominik Echterbruch

Eric Hochreiter schrieb:
>
> Ich habe eine MySQL Tabelle mit einem Feld, dass durch Kommas getrennt
> verschiedene Inhalte hat (z.B. "1,9,3,41,7,23,63").

Wieso trägst du solche Werte in eine Spalte ein? Mach doch lieber eine
weitere Tabelle, in der du die Werte zeilenweise eintragen kannst.

> Mein Problem ist nun, dass ich nicht weiß wie ich nun per SELECT
> Einträge finden kann, bei denen ich nach einem Wert (z.B. "3") in
> besagtem Feld suchen muss.

Kein Wunder. Dein Datenmodell scheint nicht sauber normalisiert zu sein.
Wie schon gesagt, gehören solche Inhalte in eine extra Tabelle. Und zwar
Wert für Wert in einen eigenen Datensatz.

> Also wenn das meine Tabelle ist:
> A B C
> 1 ABC DEF 5,11,4,23,64,12
> 2 HGE KEO 1,9,3,41,7,23,63
> 3 OEA EWQ 8,32,4,3
>
> will ich alle Einträge, die in Spalte C die "3" beinhalten, das wäre
> also Zeile 2 und 3.

Ich hadere mit mir selbst, ob ich dir die Lösung dazu geben soll. Ich
fürchte, daß du dann weiterhin mit diesem scheinbar defekten Modell
weiter arbeiten wirst. Aber das wird dir noch viel mehr und viel
heftigeren Ärger machen, als das aktuelle Problem.
Nun gut, ich sage dir als Stichwort mal "reguläre Ausdrücke" bzw.
"regular expressions".

> Wie muss ich das nun als SELECT WHERE Abfrage umsetzen?

Wie bereits mehrfach gesagt: gar nicht. Du solltest die Tabelle dringend
normalisieren. Zum Bleistift so:
CREATE TABLE a (aid int unsigned not null auto_increment primary key,
code1 char(3), code2 char(3));
CREATE TABLE b (aid int unsigned, zahl int unsigned);
INSERT INTO a (code1, code2) VALUES ('ABC', 'DEF'), ('HGE', 'KEO'),
('OEA', 'EWQ');
INSERT INTO b (aid, zahl) VALUES (1, 5), (1, 11), (1, 4), (1, 23);
INSERT INTO b (aid, zahl) VALUES (2, 1), (2, 9), (2, 3), (2, 41);
INSERT INTO b (aid, zahl) VALUES (3, 8), (3, 32), (3, 4), (3, 3);

Dann kannst du ganz bequem fragen:
SELECT a.aid, a.code1, a.code2
FROM a
INNER JOIN b ON b.aid = a.aid
WHERE b.zahl = 3;

und erhältst:
+-----+-------+-------+
| aid | code1 | code2 |
+-----+-------+-------+
| 2 | HGE | KEO |
| 3 | OEA | EWQ |
+-----+-------+-------+


Grüße,
Dominik
--
Wo kämen wir denn hin, wenn jeder sagen würde wo kämen wir hin, aber
niemand gehen würde um zu sehen, wohin wir kämen, wenn wir gingen?
(Autor unbekannt)

Re: Einträge überein Feld mit Array Inhalt finden

am 26.06.2007 02:28:37 von Andreas Scherbaum

Dominik Echterbruch wrote:
>
> Ich hadere mit mir selbst, ob ich dir die Lösung dazu geben soll. Ich
> fürchte, daß du dann weiterhin mit diesem scheinbar defekten Modell
> weiter arbeiten wirst. Aber das wird dir noch viel mehr und viel
> heftigeren Ärger machen, als das aktuelle Problem.
> Nun gut, ich sage dir als Stichwort mal "reguläre Ausdrücke" bzw.
> "regular expressions".

Es ginge noch einfacher. Mysql bietet direkt Unterstützung für komma-
separierte Listen. Früher[tm] hat man diese Vorgehensweise, alles mit
Komma getrennt in eine Zeile zu packen, durchaus als brauchbaren
Ersatz für z.B. fehlende Foreign Keys angesehen.

Aber du hast Recht, dieses Design ist kaputt und sollte lieber
umgeschrieben werden. Auch wenn man so eine Liste direkt durchsuchen
kann: performant ist das nicht und einen Index kann man auch nicht
auf diese Suche legen. Von daher lieber gleich richtig.


Bye

--
Andreas 'ads' Scherbaum
Failure is not an option. It comes bundled with your Microsoft product.
(Ferenc Mantfeld)

Re: Einträge über ein Feld mit Array Inhalt finden

am 26.06.2007 06:11:42 von Eric Hochreiter

"Dominik Echterbruch" schrieb:
> Eric Hochreiter schrieb:
>>
>> Ich habe eine MySQL Tabelle mit einem Feld, dass durch Kommas getrennt
>> verschiedene Inhalte hat (z.B. "1,9,3,41,7,23,63").
>
> Wieso trägst du solche Werte in eine Spalte ein? Mach doch lieber eine
> weitere Tabelle, in der du die Werte zeilenweise eintragen kannst.
>
>> Mein Problem ist nun, dass ich nicht weiß wie ich nun per SELECT
>> Einträge finden kann, bei denen ich nach einem Wert (z.B. "3") in
>> besagtem Feld suchen muss.
>
> Kein Wunder. Dein Datenmodell scheint nicht sauber normalisiert zu sein.
> Wie schon gesagt, gehören solche Inhalte in eine extra Tabelle. Und zwar
> Wert für Wert in einen eigenen Datensatz.

Ok, wenn das so absolut falsch ist, dann mach ich halt doch eine extra
Tabelle. Ich dachte eben ich könnte das ausnahmsweise mal so machen.
Wenn das Ganze natürlich so einen Performance Nachteil hat, dann mach
ich es halt doch lieber anders.

Nur rein Interessenshalber: hätte es denn außer dem Umschreiben für
obiges überhaupt eine Lösung gegeben?

Gruß
Eric

--
www.TheNGA.de - Nintendo Gaming Agency

Re: Einträge über ein Feld mit Array Inhalt finden

am 26.06.2007 09:16:15 von Claus Reibenstein

Eric Hochreiter schrieb:

> "Dominik Echterbruch" schrieb:
>
>> Eric Hochreiter schrieb:
>>
>>> Mein Problem ist nun, dass ich nicht weiß wie ich nun per SELECT
>>> Einträge finden kann, bei denen ich nach einem Wert (z.B. "3") in
>>> besagtem Feld suchen muss.
>
> Nur rein Interessenshalber: hätte es denn außer dem Umschreiben für
> obiges überhaupt eine Lösung gegeben?

Ja: SELECT * FROM tabelle
WHERE C = '3' OR C LIKE '3,%' OR C LIKE '%,3' OR C LIKE '%,3,%';

Gruß. Claus

Re: Einträge über ein Feld mit Array Inhalt finden

am 26.06.2007 11:46:44 von Dominik Echterbruch

Andreas Scherbaum schrieb:
> Dominik Echterbruch wrote:
>> Ich hadere mit mir selbst, ob ich dir die Lösung dazu geben soll. Ich
>> fürchte, daß du dann weiterhin mit diesem scheinbar defekten Modell
>> weiter arbeiten wirst. Aber das wird dir noch viel mehr und viel
>> heftigeren Ärger machen, als das aktuelle Problem.
>> Nun gut, ich sage dir als Stichwort mal "reguläre Ausdrücke" bzw.
>> "regular expressions".
>
> Es ginge noch einfacher. Mysql bietet direkt Unterstützung für komma-
> separierte Listen.

Huch! Die kenne ich noch gar nicht. Hast du dazu mal eine Stelle im
Handbuch für mich?

Grüße,
Dominik
--
Wo kämen wir denn hin, wenn jeder sagen würde wo kämen wir hin, aber
niemand gehen würde um zu sehen, wohin wir kämen, wenn wir gingen?
(Autor unbekannt)

Re: Einträge über ein Feld mit Array Inhalt finden

am 26.06.2007 11:49:33 von Dominik Echterbruch

Claus Reibenstein schrieb:
> Eric Hochreiter schrieb:
>
>> "Dominik Echterbruch" schrieb:
>>
>>> Eric Hochreiter schrieb:
>>>
>>>> Mein Problem ist nun, dass ich nicht weiß wie ich nun per SELECT
>>>> Einträge finden kann, bei denen ich nach einem Wert (z.B. "3") in
>>>> besagtem Feld suchen muss.
>> Nur rein Interessenshalber: hätte es denn außer dem Umschreiben für
>> obiges überhaupt eine Lösung gegeben?
>
> Ja: SELECT * FROM tabelle
> WHERE C = '3' OR C LIKE '3,%' OR C LIKE '%,3' OR C LIKE '%,3,%';

Oder eben einen regulären Ausdruck wie (ohne nach der genauen Syntax
geschaut zu haben):
SELECT *
FROM tabelle
WHERE C ~ '(^|,)3(,|$)';

Grüße,
Dominik
--
Wo kämen wir denn hin, wenn jeder sagen würde wo kämen wir hin, aber
niemand gehen würde um zu sehen, wohin wir kämen, wenn wir gingen?
(Autor unbekannt)

Re: Einträge über ein Feld mit Array Inhalt finden

am 26.06.2007 12:06:14 von Eric Hochreiter

"Dominik Echterbruch" schrieb:
> Claus Reibenstein schrieb:
>> Eric Hochreiter schrieb:
>>
>>> "Dominik Echterbruch" schrieb:
>>>
>>>> Eric Hochreiter schrieb:
>>>>
>>>>> Mein Problem ist nun, dass ich nicht weiß wie ich nun per SELECT
>>>>> Einträge finden kann, bei denen ich nach einem Wert (z.B. "3") in
>>>>> besagtem Feld suchen muss.
>>> Nur rein Interessenshalber: hätte es denn außer dem Umschreiben für
>>> obiges überhaupt eine Lösung gegeben?
>>
>> Ja: SELECT * FROM tabelle
>> WHERE C = '3' OR C LIKE '3,%' OR C LIKE '%,3' OR C LIKE '%,3,%';
>
> Oder eben einen regulären Ausdruck wie (ohne nach der genauen Syntax
> geschaut zu haben):
> SELECT *
> FROM tabelle
> WHERE C ~ '(^|,)3(,|$)';

Danke.

Und damit kann es nicht passieren, dass er bei 3 auch z.B. 63 oder 36
erkennt? Muss zugeben, dass diese Ausdrücke für mich noch ziemlich neu
sind und bei mir noch leichte Verständnisprobleme vorhanden sind.

Ich werde das Ganze aber jetzt wie gesagt in eine extra Tabelle packen,
aber gut zu wissen, dass es gehen würde.

Gruß
Eric

--
www.TheNGA.de - Nintendo Gaming Agency

Re: Einträge über ein Feld mit Array Inhalt finden

am 26.06.2007 12:33:56 von Gregor Kofler

Eric Hochreiter meinte:
> "Dominik Echterbruch" schrieb:

>> SELECT *
>> FROM tabelle
>> WHERE C ~ '(^|,)3(,|$)';
>
> Danke.
>
> Und damit kann es nicht passieren, dass er bei 3 auch z.B. 63 oder 36
> erkennt?

Nein.

Gruß, Gregor


--
http://www.gregorkofler.at ::: Landschafts- und Reisefotografie
http://www.image2d.com ::: Bildagentur für den alpinen Raum

Re: Einträge über ein Feld mit Array Inhalt finden

am 26.06.2007 13:05:20 von dnoeth

Claus Reibenstein wrote:

>>>> Mein Problem ist nun, dass ich nicht weiß wie ich nun per SELECT
>>>> Einträge finden kann, bei denen ich nach einem Wert (z.B. "3") in
>>>> besagtem Feld suchen muss.
>> Nur rein Interessenshalber: hätte es denn außer dem Umschreiben für
>> obiges überhaupt eine Lösung gegeben?
>
> Ja: SELECT * FROM tabelle
> WHERE C = '3' OR C LIKE '3,%' OR C LIKE '%,3' OR C LIKE '%,3,%';

Womit auch 312 oder 53 gefunden wird...

where concat(',',C,',') like concat('%,',suchstring,',%')

Das ist aber immer noch nur eine Notlösung für ein falsches Datenmodell...

Dieter

Re: Einträge überein Feld mit Array Inhalt finden

am 26.06.2007 14:17:19 von Andreas Scherbaum

Claus Reibenstein <4spammersonly@web.de> wrote:
> Eric Hochreiter schrieb:
>
>> "Dominik Echterbruch" schrieb:
>>
>>> Eric Hochreiter schrieb:
>>>
>>>> Mein Problem ist nun, dass ich nicht weiß wie ich nun per SELECT
>>>> Einträge finden kann, bei denen ich nach einem Wert (z.B. "3") in
>>>> besagtem Feld suchen muss.
>>
>> Nur rein Interessenshalber: hätte es denn außer dem Umschreiben für
>> obiges überhaupt eine Lösung gegeben?
>
> Ja: SELECT * FROM tabelle
> WHERE C = '3' OR C LIKE '3,%' OR C LIKE '%,3' OR C LIKE '%,3,%';

Leute, nun sagt bloss, ich kenne Mysql besser als ihr ...
Wobei ... eigentlich sollte mir das peinlich sein.


----- cut -----
mysql> create table set_test (id int, test text);
Query OK, 0 rows affected (0.34 sec)

mysql> insert into set_test (id, test) values (1, 'a,b,c');
Query OK, 1 row affected (0.06 sec)

mysql> insert into set_test (id, test) values (2, 'd,b');
Query OK, 1 row affected (0.00 sec)

mysql> insert into set_test (id, test) values (3, 'c,a');
Query OK, 1 row affected (0.01 sec)

mysql> insert into set_test (id, test) values (4, 'c,a,ab');
Query OK, 1 row affected (0.06 sec)

mysql> insert into set_test (id, test) values (5, 'c,a,ba');
Query OK, 1 row affected (0.00 sec)

mysql> insert into set_test (id, test) values (6, 'c,ba,a');
Query OK, 1 row affected (0.00 sec)

mysql> select id,test from set_test where find_in_set('b', test);
+------+-------+
| id | test |
+------+-------+
| 1 | a,b,c |
| 2 | d,b |
+------+-------+
2 rows in set (0.13 sec)
----- cut -----


Bye

--
Andreas 'ads' Scherbaum
Failure is not an option. It comes bundled with your Microsoft product.
(Ferenc Mantfeld)

Re: Einträge über ein Feld mit Array Inhalt finden

am 26.06.2007 17:35:20 von Claus Reibenstein

Dieter Noeth schrieb:

> Claus Reibenstein wrote:
>
>> Ja: SELECT * FROM tabelle
>> WHERE C = '3' OR C LIKE '3,%' OR C LIKE '%,3' OR C LIKE '%,3,%';
>
> Womit auch 312 oder 53 gefunden wird...

Wieso?

Gruß. Claus

Re: Einträge über ein Feld mit Array Inhalt finden

am 26.06.2007 18:26:35 von dnoeth

Claus Reibenstein wrote:

>>> Ja: SELECT * FROM tabelle
>>> WHERE C = '3' OR C LIKE '3,%' OR C LIKE '%,3' OR C LIKE '%,3,%';
>> Womit auch 312 oder 53 gefunden wird...
>
> Wieso?

Stimmt, vielleicht sollte ich genauer lesen, irgendwie hab ich noch paar
% gesehen :-)

Dieter

Re: Einträge überein Feld

am 26.06.2007 20:10:02 von Norbert Tretkowski

Am Dienstag, den 26.06.2007, 11:46 +0200 schrieb Dominik Echterbruch:
> Andreas Scherbaum schrieb:
> > Es ginge noch einfacher. Mysql bietet direkt Unterstützung fü=
r komma-
> > separierte Listen.
>=20
> Huch! Die kenne ich noch gar nicht. Hast du dazu mal eine Stelle im=20
> Handbuch für mich?

http://www.mysql.org/doc/refman/5.0/en/csv-storage-engine.ht ml

Norbert

Re: Einträge über ein Feld mit Array Inhalt finden

am 27.06.2007 22:45:44 von Dominik Echterbruch

Eric Hochreiter schrieb:
>
>> SELECT *
>> FROM tabelle
>> WHERE C ~ '(^|,)3(,|$)';
>
> Muss zugeben, dass diese Ausdrücke für mich noch ziemlich neu
> sind und bei mir noch leichte Verständnisprobleme vorhanden sind.

OK, dann eine kurze Erläuterung:
() bedeutet, daß hier ein Ausdruck kommt, der erst mal getrennt vom Rest
zu betrachten ist.
^ bedeutet Anfang des Strings
| heißt "oder"
, ist das Komma (wäre hätte es gedacht? ;))
(^|,) heißt also, daß wir entweder am Anfang des Strings stehen müssen,
oder ein Komma da sein muß

Dahinter dann deine 3, die ja in jedem Fall allein stehen muß.

Und dann sagen wir mit (,|$), daß entweder wieder ein Komma oder das
Ende des Strings kommen muß. Letzteres wird durch das $ angezeigt.

Hier [1] gibt es eine sehr umfangreiche und auch halbwegs verständliche
Erklärung zu den regulären Ausdrücken (leider auf Englisch). Es ist kein
leichtes Thema, wenn man sich noch nie damit beschäftigt hat, aber wenn
man es mal in den Grundzügen verstanden hat, ist es extrem mächtig und
hilft einem aus so mancher Klemme. Allerdings immer mit dem Problem, daß
die RE-Engine ein Monster und dementsprechend langsam ist.

[1] http://de2.php.net/manual/de/reference.pcre.pattern.syntax.p hp

Grüße,
Dominik
--
Wo kämen wir denn hin, wenn jeder sagen würde wo kämen wir hin, aber
niemand gehen würde um zu sehen, wohin wir kämen, wenn wir gingen?
(Autor unbekannt)

Re: Einträge über ein Feld mit Array Inhalt finden

am 28.06.2007 08:08:54 von Claus Reibenstein

Dominik Echterbruch schrieb:

> Oder eben einen regulären Ausdruck wie (ohne nach der genauen Syntax
> geschaut zu haben):
> SELECT *
> FROM tabelle
> WHERE C ~ '(^|,)3(,|$)';

Ich finde keinen binären ~-Operator im MySQL 5.1 Referenzhandbuch. Wo
hast Du diesen her?

Gruß. Claus

Re: Einträge über ein Feld mit Array Inhalt finden

am 13.07.2007 20:28:13 von Dominik Echterbruch

Claus Reibenstein schrieb:
>
>> Oder eben einen regulären Ausdruck wie (ohne nach der genauen Syntax
>> geschaut zu haben):
>> SELECT *
>> FROM tabelle
>> WHERE C ~ '(^|,)3(,|$)';
>
> Ich finde keinen binären ~-Operator im MySQL 5.1 Referenzhandbuch. Wo
> hast Du diesen her?

Keine Ahnung. Ich finde das Zeichen ganz hübsch. Da ahb ich es einfach
mal da hin getippt...
Wie ich bereits unmittelbar über der Abfrge geschrieben hatte, habe ich
nicht nach der Syntax geschaut. Kann auch Postgres sein, keine Ahnung.

Grüße,
Dominik
--
Wo kämen wir denn hin, wenn jeder sagen würde wo kämen wir hin, aber
niemand gehen würde um zu sehen, wohin wir kämen, wenn wir gingen?
(Autor unbekannt)