2016-04-17 8 views
1

I postgresql Tabelle, die wie folgt aussieht:Gibt es eine Möglichkeit zu wählen, wie mit benutzerdefinierten Separator

+----+---------------------+ 
| id |  names  | 
+----+---------------------+ 
| 1 | foo|bar and biz|pop | 
+----+---------------------+ 

Ich möchte Zeile auszuwählen angegebenen Namen enthält. So etwas wie

SELECT "id" FROM "table" WHERE "names" LIKE '%foo%'; 
id 
----- 
1 
(1 row) 

Ich mag die Abfrage diese Zeilen als auch zurück, wenn ich für bar and biz fragen, aber nichts zurück, wenn ich von bar fragen.

Für jetzt bin ich hinzufügen Rohr Symbole am Anfang und am Ende der Linie und fragen Sie LIKE '%|bar and biz|%'. Wie auch immer, ich frage mich, ob es eine Möglichkeit gibt, diese Reihe ohne zusätzliche Rohre zu finden.

Gibt es eine Möglichkeit, solche Abfrage in Postgresql zu tun?

UPD: Es scheint wie ich mein Problem schlecht erklären. Nun, ich will folgendes:

SELECT "id" FROM "table" WHERE "names" LIKE '%bar and biz%'; 
id 
----- 
1 
(1 row) 

und

SELECT "id" FROM "table" WHERE "names" LIKE '%bar%'; 
id 
----- 
(0 rows) 

Antwort

2

Zuerst mehrere Werte in einer einzigen Spalte zu speichern ist eine schlechte Idee:

  • SQL bei String-Operationen nicht sehr gut ist.
  • Solche Operationen können keine Indizes verwenden.
  • Sie können keine Fremdschlüsselbeziehungen zum Validieren von Werten verwenden.

Stattdessen sollten Sie eine Junction-Tabelle verwenden. Postgres hat auch andere Lösungen zum Speichern von Listen, wie Arrays und JSON.

Manchmal sind wir mit schlechten Designentscheidungen anderer Menschen festgefahren.Eine Methode like Verwendung ist:

SELECT "id" 
FROM "table" 
WHERE '|' || "names" || '|' LIKE '%|bar|%'; 
+0

Um ehrlich zu sein, ist diese Lösung meine und ich habe diese Spalte gerade erst erstellt. Ich habe versucht, etwas so einfach wie möglich zu erstellen, um Aliase in der Tabelle zu behalten, aber Sie haben recht, die Diskussion hier und Ihr SQL-Snippet zeigen mir, dass meine Idee völlig falsch war. Ich schreibe das besser als Array oder so. Danke für den Wissensaustausch. –

1

Haben Sie versucht, die folgenden?

where "names" = 'foo' or 
     "names" LIKE 'foo|%' or 
     "names" LIKE '%|foo' or 
     "names" LIKE '%|foo|%' 
+0

Scheint wie ich mein Problem schlecht erklären. Bitte überprüfen Sie Update in der Frage. –

+0

Es wird nicht funktionieren, wie Sie es wollen, um zu arbeiten ... –

0

Ich habe gerade in mein System eingecheckt und es funktioniert gut für mich. Vor allem verstehe ich nicht, warum Sie im Spaltennamen doppelte Anführungszeichen haben. Es wird nicht empfohlen.

Mein Tabellenschema

CREATE TABLE table (
    id int(11) unsigned NOT NULL AUTO_INCREMENT, 
    names varchar(255) DEFAULT NULL, 
    PRIMARY KEY (id) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

und Daten zu holen, ich dieses

SELECT id FROM table WHERE names LIKE '%foo%' or names LIKE '%bar and biz%'; 

aktualisieren

verwendet: -

SELECT * FROM A WHERE names LIKE '%bar%'; 

enter image description here

doppelte Anführungszeichen f entfernen rom coulmn Namen und Tabellennamen.

+0

Scheint, wie ich mein Problem schlecht erklären. Bitte überprüfen Sie Update in der Frage. Übrigens verwende ich doppelte Anführungszeichen, weil ich camel-case benannte Spalten habe und postresql konvertiert automatisch alles in Kleinbuchstaben, falls es keine doppelten Anführungszeichen gibt. –

1

Da Ihre Spalte bereits mit getrennt ist ‚|‘ Sie könnte es zu einer Reihe warf einen Einsatz der das gewünschte Ergebnis

SELECT "id" 
FROM "table" 
WHERE string_to_array(names, '|')::varchar[] @> '{bar}'::varchar[]; 
2

Während stecken mit Ihrem unglücklichen Design zu bekommen enthält, in ein Array umwandeln und verwenden Sie das ANY Konstrukt:

SELECT id 
FROM table 
WHERE 'bar' = ANY (string_to_array(names, '|')); 

Über ANY, @>, Arrays und Indizes:

Verwandte Themen