4 Stimmen

Wie wähle ich diese spezifischen Zeilen in MySQL aus?

In der MySQL-Tabelle habe ich ein Feld mit der Bezeichnung "Tag", das mehrere durch Komma getrennte Werte enthalten kann.

Ich möchte Zeilen auswählen, in denen das Feld Tag den Wert "1" enthält.

Wie würde ich meine MySQL-Anweisung schreiben, damit ich Zeilen mit Tag-Werten von "1" und "1,Cars" auswähle, aber die Zeilen mit den Tag-Werten "17" und "17,Cars" ausschließe?

Das Problem ist, dass ich den "LIKE"-Operator verwende, der aber dazu führt, dass alle vier dieser Zeilen ausgewählt werden.

Danke.

2voto

bnaul Punkte 16626

FIND_IN_SET durchsucht eine kommagetrennte Liste, z.B.:

SELECT FIND_IN_SET('b','a,b,c,d');

In diesem Fall etwas in der Größenordnung von

SELECT tag FROM table
WHERE FIND_IN_SET('1', tag) > 0

sollte das genügen.

EDIT: Es gibt tatsächlich 0 zurück, wenn keine Übereinstimmung gefunden wird, also war die NULL-Prüfung falsch.

1voto

Adriaan Stander Punkte 155899

Sie müssten wahrscheinlich etwas tun wie

WHERE Tag LIKE "1,%"
OR Tag LIKE "%,1,%"
OR Tag LIKE "%,1"
OR Tag = "1"

Damit sollten dann alle Optionen abgedeckt sein.

Vielleicht sollten Sie lieber die Verwendung von Reguläre Ausdrücke

1voto

paxdiablo Punkte 809679

Wenn Sie nur diejenigen auswählen möchten, die eine 1 enthalten, können Sie dies tun:

where colm like '1,%'
   or colm like '%,1,%'
   or colm like '%,1'
   or colm = '1'

Sie sollten sich aber darüber im Klaren sein, dass dies ein Leistungskiller sein wird. Wenn Sie immer Wenn Sie Dinge manipulieren müssen, die kleiner als eine Spalte sind, ist Ihr Datenbankschema schlecht aufgebaut. Die Grund Der Grund, warum die obige Abfrage nicht gut funktioniert, ist, dass es nicht möglich ist, Indizes zu verwenden, um schnell Zeilen zu finden, die die Abfrage erfüllen. Es wird entweder ein vollständiger Tabellen- oder Index-Scan benötigt, um die Zeilen zu erhalten.

Es wäre besser, das Schema so umzugestalten, dass die kommagetrennten Daten in Zeilen einer anderen Tabelle aufgeteilt werden.

Ein Beispiel dafür wäre etwas wie:

PrimaryTable:
    id          integer       primary key
    other_stuff varchar(250)
SecondaryTable:
    primary_id  integer       references PrimaryTable(id)
    int_val     integer
    char_val    varchar(20)
    primary key (primary_id,int_val)
    index       (int_val)

So können Sie blitzschnelle Abfragen schreiben, im Gegensatz zu dem langsamen Zeug, das Sie vorschlagen:

select p.id, p.other_stuff
from PrimaryTable p, SecondaryTable s
where p.id = s.primary_id
  and s.int_val = 1;

(oder die entsprechende explizite Join-Syntax).

Der Grund, warum diese Lösung schneller funktioniert, ist, dass sie einen Index auf SecondaryTable.int_val um schnell die relevanten Zeilen und den Primärschlüssel der beiden Tabellen für den Abgleich abzurufen.

0voto

codaddict Punkte 426877

Sie können verwenden Wortgrenzen mit REGEX als:

SELECT TAG 
FROM TABLE
WHERE TAG REGEXP '[[:<:]]1[[:>:]]';

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X