2012-04-10 5 views
0

Ich habe eine Tabelle mit einer Spalte Abstammung halten eine Liste der Vorfahren wie folgt formatiert "1/12/45". 1 ist die Wurzel, 12 ist Kinder von 1, etc ...sql in-Klausel funktioniert nicht

Ich muss alle Datensätze mit einem bestimmten Knoten/Nummer in ihrer Abstammung Liste finden. Dazu schrieb ich diese SQL-Anweisung:

select * from nodes where 1 in (nodes.ancestry) 

erhalte ich folgende Fehlerangabe: Operator existiert nicht: integer = text

Ich habe versucht, dies auch:

select * from nodes where '1' in (nodes.ancestry) 

aber es gibt nur die Datensätze mit 1 in ihrem Ahnenfeld zurück. Nicht der mit zum Beispiel 1/12/45

Was ist los?

Danke!

+2

Was haben Sie denken, dass 'in' das richtige Werkzeug war für dieser Beruf? Oder dass es auf magische Weise wissen würde, wie man die Spalte "Abstammung" interpretiert? –

+0

Wenn Sie die Möglichkeit haben, Ihre Tabellen neu zu gestalten, sollten Sie das tun. Strukturierte Informationen in solchen Strings zu halten, wird nicht empfohlen und bringt Sie nur in alle möglichen Probleme. – barsju

Antwort

2

Dieses wie ein Job klingt für LIKE, nicht IN.

Wenn wir annehmen, dass Sie für diesen Wert in einer beliebigen Position gesucht werden soll, und dann könnten wir versuchen:

select * from nodes where '/' + nodes.ancestry + '/' like '%/1/%' 

Beachten Sie, dass genaue Syntax für die String-Verkettung zwischen SQL Produkte variiert. Beachten Sie, dass ich die Spalte ancestry vorseele und angehängt habe, sodass die ersten/letzten Elemente in der Liste nicht anders behandelt werden müssen als die mittleren Elemente. Beachten Sie auch, dass wir die 1 mit /s umgeben, so dass wir keine falschen Übereinstimmungen für z.B. mit /51/ oder /12/.

+0

Wenn er '1 /' auch zusammenbringen muss, könnte er ein regexp Match benötigen. – barsju

+0

Hallo Damien, deine Lösung ist das, was ich bis jetzt benutzt habe, aber ich wollte etwas sauberer haben. IN schien mir offensichtlich, aber offensichtlich ist das nicht offensichtlich ... – ndemoreau

+0

Für die Vollständigkeit: in Postgres wird dies: Wählen Sie * von Knoten, wo '/' || nodes.ancestry || '/' wie '%/1 /%' – ndemoreau

0

In MySQL könnten Sie schreiben:

SELECT * FROM nodes 
WHERE ancestry = '1' 
    OR LEFT(ancestry, 2) = '1/' 
    OR RIGHT(ancestry, 2) = '/1' 
    OR INSTR(ancestry, '/1/') > 0 
0

Der in Bediener erwartet eine durch Kommata getrennte Liste von Werten oder ein Abfrageergebnis, das heißt:

... in (1,2,3,4,5) 

oder:

... in (select id from SomeOtherTable) 

Was Sie tun müssen, ist eine Zeichenfolge aus der erstellen Nummer, so dass Sie in der anderen Zeichenfolge suchen können.

Nur die Suche nach der Zeichenfolge '1' in der Abstammung Liste würde falsche Positive geben, wie es in der Zeichenfolge '2/12/45' finden würde. Sie müssen den Separator zu Beginn und am Ende der beiden Strings hinzuzufügen, so dass Sie für eine Zeichenfolge aussehen '/1/' in einem String wie '/1/12/45/':

select * from nodes 
where charindex('/' + convert(varchar(50), 1) + '/', '/' + nodes.ancestry + '/') <> 0 
+0

Ich habe das auch versucht: Wählen Sie * von Knoten, wo '1' in (ersetzen (nodes.ancestry, '/', ',')) aber ich bekomme das gleiche Ergebnis – ndemoreau

+0

@ ndemoreau: Sie können den 'in'-Operator nicht verwenden, um nach einer Zeichenfolge in einer anderen Zeichenfolge zu suchen. Wenn Sie den 'in'-Operator verwenden möchten, müssten Sie den String' '1/12/45'' in drei Datensätze in einer temporären Tabelle aufteilen, was eine sehr langsame Lösung wäre. – Guffa

+0

Ich verstehe das, aber warum kann ich den Operator IN nicht verwenden, um nach einer Ganzzahl in einer durch Komma getrennten Liste zu suchen. Das sollte funktionieren!? Sollte es nicht? – ndemoreau