Чтение части буквенно-цифровой строки в SQL

У меня есть таблица с одним столбцом " otname " table1.otname содержит несколько строк буквенно-цифровой строки, напоминающей следующий образец данных:

11.10.32.12.U.A.F.3.2.21.249.1

2001.1.1003.8281.A.LE.P.P.

2010.1.1003.8261.A.LE.B.B.

Я хочу прочитать четвертое число в каждой строке (часть строки выделена жирным шрифтом) и написать запрос в Oracle 10g, чтобы прочитать его описание, хранящееся в другой таблице. Моя дилемма пишет первую часть запроса, т.е. выбор четвертого числа каждой строки в таблице

Мой второй запрос будет примерно таким:

select description_text from table2 where sncode = 8281  -- fourth part of the data sample in every string

Большое спасибо.

новичок


person novice    schedule 05.08.2009    source источник


Ответы (2)


Работает с 9i+:

WITH portion AS (
  SELECT SUBSTR(t.otname, INSTR(t.otname, ".", 1, 3)+1, INSTR(t.otname, ".", 1, 4)) 'sncode'
    FROM TABLE t)
SELECT t.description_text
  FROM TABLE2 t
  JOIN portion p ON p.sncode = t.sncode

Использование SUBSTR должно быть очевидным; INSTR используется для поиска точки (.), начиная с первого символа в строке (значение параметра 1), при 3-м и 4-м появлении в строке. Возможно, вам придется вычесть единицу из позиции, возвращенной для четвертого экземпляра периода, — сначала проверьте это, чтобы убедиться, что вы получаете правильные значения:

SELECT SUBSTR(t.otname, INSTR(t.otname, ".", 1, 3)+1, INSTR(t.otname, ".", 1, 4)) 'sncode'
 FROM TABLE t

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

person OMG Ponies    schedule 05.08.2009
comment
Я получаю следующую ошибку, когда запускаю вышеуказанный запрос: ORA: 00923: ключевое слово FROM не найдено там, где ожидалось :( - person novice; 05.08.2009
comment
У меня нет экземпляра Oracle для тестирования, но единственным спорным моментом, который я вижу, будет +1 в первом INSTR. Вы уверены, что у вас есть пробел между FROM и именем таблицы в том, что вы пытались запустить? - person OMG Ponies; 05.08.2009

Более новые версии оракула (включая 10g) имеют различные функции регулярных выражений. Итак, вы можете сделать что-то вроде этого:

where sncode = to_number(regexp_replace(otname, '^(\d+\.\d+\.\d+\.(\d+))?.+$', '\2'))

Это соответствует 3 наборам цифр, за которыми следует точка, и четвертому сгруппированному набору цифр, за которым следует остальная часть строки, и возвращает строку, состоящую из всего, что полностью заменено первой группой (четвертый набор цифр). цифры).

Вот полный запрос (если я правильно понял ваше описание двух таблиц):

select t2.description_text
from table1 t1, table2 t2
where t2.sncode = to_number(regexp_replace(t1.otname, '^(\d+\.\d+\.\d+\.(\d+))?.+$', '\2'))

Еще одно немного более короткое альтернативное регулярное выражение:

where t2.sncode = to_number(regexp_replace(t1.otname, '^((\d+\.){3}(\d+))?.+$', '\3'))
person epost    schedule 05.08.2009
comment
Я выполнил ваш запрос и получил следующую ошибку: ORA-01722: неверный номер. Есть предложения? - person novice; 05.08.2009
comment
Думаю, я предположил, что ваш sncode тоже был строкой. Дайте мне знать, если это действительно число. Тем временем я обновляю свой ответ, чтобы отразить это, так что вы можете попробовать его (функция to_number). - person epost; 05.08.2009
comment
благодаря. sncode на самом деле является числом. otname является буквенно-цифровым - person novice; 05.08.2009
comment
Я все еще вижу ту же ошибку: ORA-01722: неверный номер. Любые другие идеи? - person novice; 05.08.2009
comment
Да, я собирался сказать, это не должно иметь значения на самом деле. Oracle применит это (но это может помочь в отношении индексов). Возможно, есть строки со строками, которые не соответствуют описанному вами шаблону. Я могу настроить регулярное выражение, чтобы оно справилось с этим, чтобы в таких случаях возвращалось значение null. Но можете ли вы подтвердить, возможно ли это? Или строки всегда начинаются с 4 цифр с точками? - person epost; 05.08.2009
comment
Извините, может быть, я должен был упомянуть об этом раньше. Есть нечетная строка или две, которые не соответствуют описанному шаблону, но большая часть данных соответствует описанному шаблону. - person novice; 05.08.2009
comment
Без проблем. Я только что обновил его, чтобы обрабатывать те, которые не совпадают. - person epost; 05.08.2009
comment
Привет, запрос теперь дает нулевые результаты. - person novice; 05.08.2009
comment
Это может быть проблема с чем-то еще в таблице, что будет трудно понять, не зная больше о таблицах и данных. Если следующее работает (возвращает 12), это, вероятно, какая-то другая проблема: )?.+$', '\2') из двойного - person epost; 05.08.2009
comment
...другая возможность. Когда вы скопировали мое последнее изменение, вы также скопировали последний аргумент или только само регулярное выражение? Он изменился с \1 на \2 (или в последнем примере с \2 на \3). - person epost; 05.08.2009