2017-12-19 1 views
0

Die folgende SQL repliziert das Problem, das ich versuche zu lösen. Trotz der Übergabe einer NOT IN-Klausel werden alle drei Datensätze zurückgegeben.Übergeben einer begrenzten Zeichenfolge in der NOT IN-Klausel

Ich habe eine Tabelle, die eine Zeichenfolge mit Trennzeichen enthält, die ich als Kriterien zum Ausschließen von Datensätzen aus dem Dataset verwenden möchte. Das Problem, das ich habe, ist jedoch, dass die zurückgegebene Zeichenfolge nicht in ihre begrenzten Elemente aufgeteilt wird. Ich möchte, dass die oben übersetzen:

SELECT * FROM (
SELECT 'JACK' AS VALUE FROM DUAL 
UNION 
SELECT 'JOHN' AS VALUE FROM DUAL 
UNION 
SELECT 'BOB' AS VALUE FROM DUAL 
) WHERE VALUE NOT IN ('BOB','JOHN'); 
+0

https://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:210612357425 – OldProgrammer

+0

Sie haben eine Tabelle, die eine Zeichenfolge mit Trennzeichen enthält? Warum? Wenn Sie Ihre Datenbank ordnungsgemäß verwendet und die Zeichenfolgen getrennt gespeichert haben, ist das Schreiben einer Abfrage kein Problem. –

+1

Alle drei Datensätze werden zurückgegeben, weil "BOB, JOHN" ein ** einzelner Zeichenfolgenwert ** ist. Offensichtlich "BOB, JOHN!" = "BOB" und "BOB, JOHN!" = "JACK" und "BOB, JOHN!" = "JOHN". Das Ergebnis ist also korrekt. Das Problem besteht darin, dass Sie eine Sammlung als Zeichenfolge und nicht als etwas Passendes speichern, z. B. ein Array oder eine Tabelle. – APC

Antwort

0

Sie REGEXP_SUBSTR für dieses Problem verwenden können:

SELECT * FROM (
SELECT 'JACK' AS VALUE FROM DUAL 
UNION 
SELECT 'JOHN' AS VALUE FROM DUAL 
UNION 
SELECT 'BOB' AS VALUE FROM DUAL 
) 
WHERE VALUE NOT IN (SELECT regexp_substr('BOB,JOHN','[^,]+', 1, LEVEL) FROM dual CONNECT BY regexp_substr('BOB,JOHN', '[^,]+', 1, LEVEL) IS NOT NULL) 
+0

Das Posten eines Codeblocks und das Sagen von "Verwenden Sie dieses" ist nicht die beste Hilfe ohne eine Erklärung dessen, was das Problem mit dem OP-Code war und eine Erklärung warum (und wie) Ihr Code das Problem löst. – MT0

+0

Und wo beginnt und endet das? Weiß er, was ein Substr ist? Weiß er, was reguläre Ausdrücke sind und wie sie verwendet werden? Weiß er was connect ist? Wenn er weitere Fragen hat, kann er sie fragen und ich bin bereit zu helfen. Aber ich würde es schwer haben zu erraten, welche weiteren Informationen er braucht. – aLpenbog

1

'BOB,JOHN' ist nicht eine Liste von zwei String-Werte ist es ein String-Wert ist, was geschieht, nur enthalten Komma im String und:

'JACK' = 'BOB,JOHN' 
'JOHN' = 'BOB,JOHN' 
'BOB' = 'BOB,JOHN' 

Sind alle falsch, damit Ihre Abfrage wird wieder alle Zeilen, wie durch die NOT IN Filter abgestimmt.

Sie können Ihre Werte und die Liste mit den Begrenzungszeichen umgeben und testen, ob der Wert nicht ein Unterkette der Liste ist wie folgt:

:

SELECT * 
FROM (
    SELECT 'JACK' AS VALUE FROM DUAL UNION ALL 
    SELECT 'JOHN' AS VALUE FROM DUAL UNION ALL 
    SELECT 'BOB' AS VALUE FROM DUAL 
) 
WHERE INSTR(',' || 'BOB,JOHN' || ',', ',' || value || ',') = 0 

Oder Sie eine benutzerdefinierte Sammlung verwenden können

CREATE OR REPLACE TYPE stringlist IS TABLE OF VARCHAR2(20); 

Dann nutzen Sie den MEMBER OF Operator zu testen, ob ein Wert ein Mitglied der Sammlung ist:

SELECT * 
FROM (
    SELECT 'JACK' AS VALUE FROM DUAL UNION ALL 
    SELECT 'JOHN' AS VALUE FROM DUAL UNION ALL 
    SELECT 'BOB' AS VALUE FROM DUAL 
) 
WHERE VALUE NOT MEMBER OF StringList('BOB', 'JOHN'); 
Verwandte Themen