2012-03-02 8 views
22

Я искал этот вопрос и нашел ответ в MySQL, но это один из тех инцидентов, в которых оператор не перешел в Oracle.Может ли оператор «IN» использовать LIKE-подстановочные знаки (%) в Oracle?

Can I use wildcards in "IN" MySQL statement?
довольно много суммирует мой вопрос и что я хотел бы сделать, но в Oracle

Я хотел бы найти юридический эквивалент

Select * from myTable m 
where m.status not in ('Done%', 'Finished except%', 'In Progress%') 

Спасибо за любую помощь

ответ

15
Select * from myTable m 
where m.status not like 'Done%' 
and m.status not like 'Finished except%' 
and m.status not like 'In Progress%' 
+0

Я пытался избежать длинного маршрута, но похоже, что это может быть единственный способ. – Matt

+0

@Matt. Если это всего лишь написание немного более короткого текста SQL, чем просто использовать синтаксис, предложенный в этом ответе, и учиться жить с ним , Если речь идет о LIKEing строках из другой таблицы (так что вы не можете заранее создать список значений заранее), то это совсем другая проблема, которая потребует чего-то вроде: 'JOIN OTHER_TABLE ON NOT (YOUR_TABLE.FIELD LIKE OTHER_TABLE .FIELD) '... –

+0

Я в конечном итоге использовал это для простоты, но ответы в регулярном выражении были полезны как возможность изучить новый бит Oracle. Спасибо всем – Matt

4

Это похоже на то, что вы ищете: https://forums.oracle.com/forums/thread.jspa?threadID=2140801

В принципе, вам нужно будет использовать регулярные выражения, поскольку для этого не существует ничего встроенного в oracle.

Я вытащил пример из потока и преобразовал его для ваших целей. Я сосу в регулярных выражениях, хотя, так что, возможно, потребуется отлажен :)

SELECT * 
FROM myTable m 
WHERE NOT regexp_like(m.status,'((Done^|Finished except^|In Progress^)') 
10

кажется, что вы можете использовать регулярное выражение слишком

WHERE NOT REGEXP_LIKE(field, '^Done|^Finished')

Я не уверен, насколько хорошо это будет работать, хотя. .. см here

3

Не 100%, что вы искали, но своего рода наизнанку способ сделать это:

SQL> CREATE TABLE mytable (id NUMBER, status VARCHAR2(50)); 

Table created. 

SQL> INSERT INTO mytable VALUES (1,'Finished except pouring water on witch'); 

1 row created. 

SQL> INSERT INTO mytable VALUES (2,'Finished except clicking ruby-slipper heels'); 

1 row created. 

SQL> INSERT INTO mytable VALUES (3,'You shall (not?) pass'); 

1 row created. 

SQL> INSERT INTO mytable VALUES (4,'Done'); 

1 row created. 

SQL> INSERT INTO mytable VALUES (5,'Done with it.'); 

1 row created. 

SQL> INSERT INTO mytable VALUES (6,'In Progress'); 

1 row created. 

SQL> INSERT INTO mytable VALUES (7,'In progress, OK?'); 

1 row created. 

SQL> INSERT INTO mytable VALUES (8,'In Progress Check Back In Three Days'' Time'); 

1 row created. 

SQL> SELECT * 
    2 FROM mytable m 
    3 WHERE +1 NOT IN (INSTR(m.status,'Done') 
    4   ,  INSTR(m.status,'Finished except') 
    5   ,  INSTR(m.status,'In Progress')); 

     ID STATUS 
---------- -------------------------------------------------- 
     3 You shall (not?) pass 
     7 In progress, OK? 

SQL> 
1

Несколько запутанная, но:

Select * from myTable m 
join (SELECT a.COLUMN_VALUE || b.COLUMN_VALUE status 
FROM (TABLE(Sys.Dbms_Debug_Vc2coll('Done', 'Finished except', 'In Progress'))) a 
JOIN (Select '%' COLUMN_VALUE from dual) b on 1=1) params 
on params.status like m.status; 

Это было решение для очень уникальной проблемы, но это может помочь кому-то. По существу, нет инструкции «in like», и не было никакого способа получить индекс для первых символов переменной переменной, поэтому я сделал это, чтобы сделать быструю динамику «как» для использования в SSRS.

Содержимое списка («Готово», «Готово, кроме», «Выполняется») может быть переменной.

+0

Это очень ценный ответ, так как он хорошо масштабируется для нескольких моделей. Мой вариант использования заключался в поиске внутри строки, поэтому в моем собственном ответе я применил аналогичное, но немного упрощенное решение. –

0

Ближайший юридический эквивалент незаконного синтаксиса, указанного в вопросе:

select * from myTable m 
where not exists (
    select 1 
    from table(sys.ku$_vcnt('Done', 'Finished except', 'In Progress')) patterns 
    where m.status like patterns.column_value || '%' 
) 

Оба мои и @ ответ Sethionic делают возможным перечислить шаблоны динамически (только путем выбора другого источника, чем ДОПОЛНИТЕЛЬНОЕ sys.whatever таблицы).

Обратите внимание, если мы должны были искать шаблон внутри строки (а не с самого начала) и базы данных, содержащихся, например status = 'Done In Progress', то мое решение (модифицированный для like '%' || patterns.column_value || '%') будет по-прежнему генерировать одну строку для данной записи, whileas решение @ Sethionic (модифицированное для другого вспомогательного соединения до a) создало бы несколько строк для каждого появления шаблона. Не судите, что лучше, просто знайте различия и выбирайте, что лучше подходит вам.

Смежные вопросы