2009-09-30 1 views
2

Я пытаюсь использовать предложение LIKE в инструкции SQL для соответствия определенному шаблону в Oracle.Соответствие шаблону с категорией Like

Я хотел бы сделать что-то, как например:

LIKE '[A-Z][A-Z][1-4]%' 

..но Я не могу использовать регулярное выражение, потому что это на Oracle9i (регулярное выражение поддержки пришел в 10г).

Я пытаюсь сопоставить что-то, что имеет два символа перед ним, а затем число от 1 до 4 и что независимо от этого. Я попытался это сделать, но он, похоже, не работает. Единственный способ, которым я был в состоянии заставить его работать, делая:

WHERE ... 
LIKE '%1__' OR 
LIKE '%2__' OR 
LIKE '%3__' OR 
LIKE '%4__' 

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

Любая помощь, которую вы могли бы дать, была бы весьма признательна.

ответ

3

Попробуйте это:

SELECT c1 
FROM t1 
WHERE substr(c1,1,1) IN ('A','B','C','D', 
          'E','F','G','H', 
          'I','J','K','L', 
          'M','N','O','P', 
          'Q','R','S','T', 
          'U','V','W','X', 
          'Y','Z') 
     AND substr(c1,2,1) IN ('A','B','C','D', 
           'E','F','G','H', 
           'I','J','K','L', 
           'M','N','O','P', 
           'Q','R','S','T', 
           'U','V','W','X', 
           'Y','Z') 
     AND substr(c1,3,1) IN ('1','2','3','4') 
/

Если вы хотите также, чтобы соответствовать строчные буквы, а затем применить функцию верхнего() в 2 первых зиЬзЬг(): например. где верхний (подстрока (c1,1,1)) в ...

Performance

Я протестировал производительность запроса с REGEXP_LIKE и без. Как вы можете видеть, запрос без функции regexp_like был на 100% быстрее. (Примечание. Оба querys сделал мягкую разобрана)

SQL> select count(*) from t1;                              

    COUNT(*) 
---------- 
    458752 

Elapsed: 00:00:00.02 
SQL> set timing off;                                 
SQL> select count(*) from t1;                              

    COUNT(*) 
---------- 
    458752 

SQL> set timing on;                                 
SQL> select count(*) from t1 where regexp_like(c1, '[A-Z][A-Z][1-4].*');                  

    COUNT(*) 
---------- 
    65536 

Elapsed: 00:00:02.66 
SELECT count(*) 
FROM t1 
WHERE substr(c1,1,1) IN ('A','B','C','D', 
          'E','F','G','H', 
          'I','J','K','L', 
          'M','N','O','P', 
          'Q','R','S','T', 
          'U','V','W','X', 
          'Y','Z') 
     AND substr(c1,2,1) IN ('A','B','C','D', 
           'E','F','G','H', 
           'I','J','K','L', 
           'M','N','O','P', 
           'Q','R','S','T', 
           'U','V','W','X', 
           'Y','Z') 
     AND substr(c1,3,1) IN ('1','2','3','4') 
18/                                    

    COUNT(*) 
---------- 
    65536 

Elapsed: 00:00:01.15 
SQL> 

Второй метод

Получить значения ASCII от A, Z, 1 и 4

SQL> select ascii('A') from dual;                              

ASCII('A') 
---------- 
     65 


SQL> select ascii('Z') from dual;                              

ASCII('Z') 
---------- 
     90 


SQL> select ascii('1') from dual;                              

ASCII('1') 
---------- 
     49 

SQL> select ascii('4') from dual;                              

ASCII('4') 
---------- 
     52 

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

SELECT count(*) 
FROM t1 
WHERE ascii(substr(c1,1,1)) BETWEEN 65 AND 90 
     AND ascii(substr(c1,2,1)) BETWEEN 65 AND 90 
     AND ascii(substr(c1,3,1)) BETWEEN 49 AND 52 
/
+0

Если бы я хотел сопоставить третьего символа перед номером, который мог бы или не был бы там, что бы я мог сделать со вторым методом (ASCII), чтобы это разрешить? – 2009-10-01 15:02:48

+0

Просто сделайте WHERE substr (c1,1,1) между «A» и «Z» ... вместо того, где ascii (substr (c1,1,1)) МЕЖДУ 65 И 90. – tuinstoel

+0

Надеюсь, это было не в меру вашего сравнительного тестирования. Некоторые из сбережений могут исходить из того, что ваши строки были в памяти из первого запроса. Кроме того, работает ли ASCII трюк с многобайтовыми наборами символов? Я не знаю, просто спрашиваю. – DCookie

0

Я думаю, вы хотите использовать REGEXP_LIKE, а не как.

WHERE REGEXP_LIKE (fieldName, '[A-Z] {2} [1-4]?. +', 'I');

+2

И как бы вы сделали это до 10g, когда регулярные выражения не поддерживались? –

+0

Да, я бы с легкостью использовал REGEXP_LIKE, но, как упоминалось в rexem, поддержка до 10g не поддерживается. – 2009-09-30 17:56:15

+1

Сверните свой собственный REGEXP_LIKE, я полагаю ... – DCookie

5

неуклюжие, но возможно:

select * 
    from <your_table> 
where TRANSLATE(SUBSTR(<blah>,1,3),'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234', 
            'AAAAAAAAAAAAAAAAAAAAAAAAAA1111') = 'AA1'; 

может удовлетворить ваши потребности ....

EDIT: Зарегистрировано XLNT предложения по @Hobo перевести подстроку, а не принимать подстроку переведенной строки ...

+0

Я думал об аналогичных строках, но используя REPLACE ... –

+3

+1. Хотя если длинный, вы бы лучше сделали перевод (substr (, 1,3), «ABC ...», «AAA ...»)? Я предполагаю, что перевод на более короткой строке дешевле, и время для получения подстроки в обоих случаях будет одинаковым. – Hobo

+0

Хорошая точка ........... – DCookie

1

Я рекомендую использовать INSTR:

INSTR(t.column, '1', 3, 1) > 0 OR 
INSTR(t.column, '2', 3, 1) > 0 OR 
INSTR(t.column, '3', 3, 1) > 0 OR 
INSTR(t.column, '4', 3, 1) > 0 

Проблема с использованием шаблона в LIKE заключается в отсутствии контроля над тем, где в столбце значение 1/2/3/4/и т. Д. Появится, это может быть в конце.

DCookie является правильным - этот ответ не имеет, если есть числовые данные в этом месте. Но это все же лучше, чем использование LIKE с подстановочными знаками.

+0

Как насчет ведущих [A-Z] [A-Z]? – DCookie

1

Общая дикая карточка, но все равно предложит ее.

Установлена ​​ли в вашей базе данных 9i набор инструментов PL/SQL Web Toolkit? Причина для запроса заключается в том, что один из наших клиентов указал, что существует ограниченная поддержка регулярных выражений, используя один из поставляемых вместе с ним пакетов.

Пакет называется owa_pattern и только 9i ссылку я смог найти это one

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

1

Если вы действительно хотите использовать reg exps, вы можете разработать обработанную Java-версию proc и сопроводительную упаковку pl/sql. (Я предполагаю, что версия Java, поддерживаемая в Oracle 9, поддерживает reg exps, я не уверен на 100%). Вы можете вызывать этот java-файл с помощью оболочки pl/sql в вашем заявлении select.

Но более легко и быстрее:

SELECT c1 
FROM t1 
WHERE substr(c1,1,1) between 'A' and 'Z' 
AND substr(c1,2,1) between 'A' and 'Z' 
AND substr(c1,3,1) IN ('1','2','3','4') 

Вариант решения zürigschnäzlets «ы без использования функции ascci.

+0

+1 для предложения java и более чистого примера. – DCookie

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

  • Нет связанных вопросов^_^