|
Программирование >> Преобразование значений null
В данном случае строк в таблице на одну меньше, чем значений в строке. Выбор необходимых значений обеспечит функция SUBSTRING INDEX: select iter.pos,src.name name1, substring index(src.name ,iter.pos) name2, substring index( substring index(src.name ,iter.pos) ,-1) name3 from (select id pos from t10) iter, V src where iter.pos <= length(src.name)-length(replace(src.name ,)) +-----+--------------------------------+--------------------------+--------- + pos name1 name2 name3 +-----+--------------------------------+--------------------------+--------- + 1 mo,larry,curly mo mo 2 mo,larry,curly mo,larry larry 1 tina,gina,jaunita,regina,leena tina tina 2 tina,gina,jaunita,regina,leena tina,gina gina 3 tina,gina,jaunita,regina,leena tina,gina,jaunita jaunita 4 tina,gina,jaunita,regina,leena tina,gina,jaunita,regina regina +-----+--------------------------------+--------------------------+--------- + Чтобы продемонстрировать работу функции SUBSTRING INDEX, показаны три поля имен. Внутренний вызов возвращает все символы, расположенные левее и-ной запятой. Внешний вызов возвращает все, что находится правее первой обнаруженной запятой (начиная с конца строки). Последний шаг - выбрать значения, для которых POS равно и, в данном случае нас интересует 2, и поместить их в столбец NAME3. Oracle Вложенный запрос осуществляет обход каждой строки. То, сколько раз будет возвращена строка, зависит от количества значений в ней. Количество значений в строке определяется посредством подсчета числа разделителей в ней. Поскольку каждая строка заключена в запятые, количество значений в строке равно числу запятых минус один. Потом строки объединяются оператором UNION и добавляются в таблицу с кардинальностью, не меньшей количества значений в самой длинной строке. Функции SUBSTR и INSTR используют значение POS для синтаксического разбора каждой строки: select iter.pos, src.name, substr( src.name, instr( src.name ,1,iter.pos instr( src.name ,1,iter.pos+1 ) -instr( src.name ,1,iter.pos )-1) sub from (select ,name, as name from v) src, (select rownum pos from emp) iter where iter.pos < length(src.name)-length(replace(src.name )) POS NAME SUB 1 ,mo,larry,curly, mo 1 , tina,gina,]aunita,regina,leena, tina 2 ,mo,larry,curly, larry 2 , tina,gina,]aunita,regina,leena, gina 3 ,mo,larry,curly, curly 3 , tina,gina,]aunita,regina,leena, jaunita 4 , tina,gina,]aunita,regina,leena, regina 5 , tina,gina,]aunita,regina,leena, leena Первый вызов INSTR в SUBSTR определяет начальную позицию необходимой нам подстроки. Следующий вызов INSTR в SUBSTR находит позицию п-ной запятой (совпадает с начальной позицией), а также п-ной+1 запятой. Разность этих значений соответствует длине извлекаемой подстроки. Поскольку в результате синтаксического разбора каждое значение занимает отдельную строку, для получения п-ной подстроки просто задаем WHERE POS = п (в данном случае where POS = 2, т. е. получаем вторую подстроку списка). PostgreSQL Вложенный запрос Х осуществляет обход всех строк. Число возвращенных строк зависит от количества значений в каждой строке. Чтобы найти, сколько значений в каждой строке, находим число разделителей в ней и добавляем единицу. Функция SPLIT PART использует значения столбца POS для поиска п-ного разделителя и раскладывает строку на значения: select iter.pos, src.name as name1, split part(src.name ,iter.pos) as name2 from (select id as pos from t10) iter, (select cast(name as text) as name from v) src where iter.pos <= length(src.name)-length(replace(src.name ,))+1 pos name1 name2 -----+--------------------------------+---------1 mo,larry,curly mo 2 mo,larry,curly larry 3 mo,larry,curly curly 1 tina,gina,]aunita,regina,leena tina 2 tina,gina,]aunita,regina,leena gina 3 tina,gina,]aunita,regina,leena jaunita 4 tina,gina,jaunita,regina,leena regina 5 tina,gina,jaunita,regina,leena leena Здесь показаны два столбца имен, чтобы можно было увидеть, как SPLIT PART проводит синтаксический разбор строк, используя значение POS. После того как разбор всех строк завершен, заключительный шаг - выбрать строки, в которых значение POS равно п-ной подстроке, в данном случае 2. 111 22 3 4 Решение Решение опирается на встроенные функции, предоставляемые СУБД. Ключом к решению, независимо от СУБД, является выявление точек и выбора чисел, их окружающих. С помощью рекурсивного блока WITH моделируйте перебор IP-адреса и используйте функцию SUBSTR для синтаксического разбора. Добавьте в начало IP-адреса точку с целью обеспечения единообразия при обработке каждой группы чисел. 1 with x (pos,ip) as ( 2 values (1,.92.111.0.222) 3 union all 4 select pos+1,ip from x where pos+1 <= 20 6 select max(case when rn=1 then e end) a, 7 max(case when rn=2 then e end) b, 8 max(case when rn=3 then e end) c, 9 max(case when rn=4 then e end) d 10 from ( 11 select pos,c,d, 12 case when posstr(d,.) > 0 then substr(d,1,posstr(d,.)-1) 13 else d 14 end as e, 15 row number() over(order by pos desc) rn 16 from ( 17 select pos, ip,right(ip,pos) as c, substr(right(ip,pos),2) as d 18 from x 19 where pos <= length(ip) 20 and substr(right(ip,pos),1,1) = 21 ) x 22 ) y Синтаксический разбор IP-адреса Задача Требуется провести синтаксический разбор IP-адреса и разместить его поля в отдельные столбцы. Рассмотрим следующий IP-адрес: 111.22.3.4 В результате запроса должен быть получен такой результат: A B C D
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |