Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 сравнение содержимого строк  [new]
boles
Member

Откуда:
Сообщений: 34
Добрый день!

Помогите, плиз, написать следующий запрос:
имеется 2 строки, в которых через запятую записаны элементы, например, номера

str1 = 1, 2, 4, 6, 8, 9, 10
str2 = 1, 3, 5, 7, 9

Хочется выбирать записи из таблицы при условии, что хотя бы один элемент присутствует в обеих строках (в данном примере элементы 1 и 9).

Как можно организовать такое действо?

Заранее спасибо!
15 май 07, 15:11    [4139497]     Ответить | Цитировать Сообщить модератору
 Re: сравнение содержимого строк  [new]
NightGhost
Member

Откуда:
Сообщений: 629
по этой ссылке преобразоввание строки с разделителями в коллекцию


select /*+ORDERED*/ * from table(....) T1, table(....) T2, YOUR_TABLE t3
where 
 T1.col = T2.col and
  T1.col = t3.col
15 май 07, 15:29    [4139589]     Ответить | Цитировать Сообщить модератору
 Re: сравнение содержимого строк  [new]
radik_cherry
Member

Откуда:
Сообщений: 39
boles

Помогите, плиз, написать следующий запрос:
имеется 2 строки, в которых через запятую записаны элементы, например, номера

str1 = 1, 2, 4, 6, 8, 9, 10
str2 = 1, 3, 5, 7, 9

Хочется выбирать записи из таблицы при условии, что хотя бы один элемент присутствует в обеих строках (в данном примере элементы 1 и 9).



А может лучше структуру переделать. Вынести элементы в отдельную таблицу.
Потому как в таком виде первая нормальная форма идет лесом :(
15 май 07, 15:30    [4139600]     Ответить | Цитировать Сообщить модератору
 Re: сравнение содержимого строк  [new]
db-man
Guest
Смешной вариант (для номеров):

with v as (select rownum rn from dual connect by level <= 100)
select rn from v
where ',' || replace('1, 2, 4, 6, 8, 9, 10', ' ', '') || ',' like '%,'||rn||',%'
intersect
select rn from v
where ',' || replace(' 1, 3, 5, 7, 9', ' ', '') || ',' like '%,'||rn||',%'
15 май 07, 15:32    [4139613]     Ответить | Цитировать Сообщить модератору
 Re: сравнение содержимого строк  [new]
Ales Protiv
Member

Откуда: Прага
Сообщений: 1872
вариант не только для номеров (не забудьте порезать пробелы):
with
  v as (select rownum rn from dual connect by level <= 100),
  v1 as (select column_value a from 
      table(xmlsequence(extract(xmltype('<b><a>'||replace('1,2,4,6,8,9,10',',','</a><a>')||'</a></b>'),'//a')))),
  v2 as (select column_value b from
      table(xmlsequence(extract(xmltype('<b><a>'||replace('1,3,5,7,9',',','</a><a>')||'</a></b>'),'//a'))))
----------------------------------
select rn from v, v1, v2
  where rn = extractvalue(a,'//a')
  and rn = extractvalue(b,'//a')
/

        RN
----------
         1
         9

15 май 07, 16:31    [4140026]     Ответить | Цитировать Сообщить модератору
 Re: сравнение содержимого строк  [new]
Stax..
Guest
boles
Добрый день!

Помогите, плиз, написать следующий запрос:
имеется 2 строки, в которых через запятую записаны элементы, например, номера

str1 = 1, 2, 4, 6, 8, 9, 10
str2 = 1, 3, 5, 7, 9

Хочется выбирать записи из таблицы при условии, что хотя бы один элемент присутствует в обеих строках (в данном примере элементы 1 и 9).

Как можно организовать такое действо?

Заранее спасибо!

что-то я не могу проблему понять

  1  select * from (
  2  select rownum rn from dual connect by level <= 100) t
  3* where rn in (1, 2, 4, 6, 8, 9, 10) and rn in (1, 3, 5, 7, 9)
SQL> /

       RN
---------
        1
        9
......
stax
15 май 07, 20:30    [4141303]     Ответить | Цитировать Сообщить модератору
 Re: сравнение содержимого строк  [new]
Elic
Member

Откуда:
Сообщений: 29980
Stax..
boles
имеется 2 строки, в которых через запятую записаны элементы
что-то я не могу проблему понять
  3* where rn in (1, 2, 4, 6, 8, 9, 10) and rn in (1, 3, 5, 7, 9)
15 май 07, 20:42    [4141322]     Ответить | Цитировать Сообщить модератору
 Re: сравнение содержимого строк  [new]
Stax..
Guest
Elic
Stax..
boles
имеется 2 строки, в которых через запятую записаны элементы
что-то я не могу проблему понять
  3* where rn in (1, 2, 4, 6, 8, 9, 10) and rn in (1, 3, 5, 7, 9)


аааааа, проблема в in "строка"

та много ж раз решали
1) instr(...)<>0
2) развернуть строку в "табличку"
......
stax
15 май 07, 21:05    [4141356]     Ответить | Цитировать Сообщить модератору
 Re: сравнение содержимого строк  [new]
Elic
Member

Откуда:
Сообщений: 29980
Stax..
та много ж раз решали
Оттого и неинтересно
15 май 07, 21:16    [4141388]     Ответить | Цитировать Сообщить модератору
 Re: сравнение содержимого строк  [new]
boles
Member

Откуда:
Сообщений: 34
Всем спасибо, однако, есть ограничения, о которых я не упомянул, т.к. не думал, что они окажутся существенными:

1) нет возможности писать функции, создавать новые таблички и т.д.
2) вариант с перечислением номеров слишком упрощен, т.к. в строке могут оказаться номера 1 и 11, соответственно при проверке instr('11', '1') <> 0 даст true

а если говорить еще более точно, то строки выглядт так:

str1 = 'abc 1234, dcvffds 5678, ...'
str2 = '11, 560, 1741, 1234'

как посоветуете поступить при таких строках?

Заранее спасибо!!!
16 май 07, 09:27    [4142199]     Ответить | Цитировать Сообщить модератору
 Re: сравнение содержимого строк  [new]
Proteus
Member

Откуда:
Сообщений: 1348
развернуть обе с троки в таблицы четез xml например (здесь вы определиите что является значением а что разделителем) и выбрать пересечение.
16 май 07, 09:49    [4142292]     Ответить | Цитировать Сообщить модератору
 Re: сравнение содержимого строк  [new]
Bely
Member

Откуда: Москва
Сообщений: 1903
boles
2) вариант с перечислением номеров слишком упрощен, т.к. в строке могут оказаться номера 1 и 11, соответственно при проверке instr('11', '1') <> 0 даст true

Если писать неправильно, то правильная функция не поможет.
instr(','||'11'||',', ',1,') <> 0;  -- Почувствуйте разницу

boles
str1 = 'abc 1234, dcvffds 5678, ...'
str2 = '11, 560, 1741, 1234'

как посоветуете поступить при таких строках?

1) Удалить лишнее (например используя translate() )
2) После этого воспользоваться одним из советов приведенным выше.

Хоть в табличку перегонять, хоть через INSTR
16 май 07, 10:49    [4142713]     Ответить | Цитировать Сообщить модератору
 Re: сравнение содержимого строк  [new]
valerytin
Member [заблокирован]

Откуда: Moscow
Сообщений: 146
-- 1) нет возможности писать функции, создавать новые таблички и т.д.
-- 2) вариант с перечислением номеров слишком упрощен, т.к. в строке могут оказаться номера 1 и 11, соответственно при проверке instr('11', '1') <> 0 даст true
-- а если говорить еще более точно, то строки выглядт так:
-- str1 = 'abc 1234, dcvffds 5678, ...'
-- str2 = '11, 560, 1741, 1234'

-- немного громоздко, но годится для 8i+:
select
 t.* from <ВАША ТАБЛИЦА> t
where
--------------------------------------------------------------------------------
 exists
--------------------------------------------------------------------------------
 (
-- вхождение слова из <ПОЛЯ ВАШЕЙ ТАБЛИЦЫ> в строку  'abc 1234, dcvffds 5678, ...' str1:
  select 1
  from 
  (
   select
-- 'слова' как непрерывные последовательности любых символов между пробелами:
    substr(s.nstr,instr(s.nstr,' ',1,rownum)+1,
     instr(s.nstr,' ',1,rownum+1)-instr(s.nstr,' ',1,rownum)-1) wd,
    s.fmt
   from 
   (
    select
-- заменяем все разделители пробелами и обрамляем пробелами строку:
     ' '||translate(str,' '||fmt,rpad(' ',100,' '))||' ' nstr,
     fmt
    from ( 
     select
       'abc 1234, dcvffds 5678, ...' str, -- произвольная строка с разделителями
-- символы, которые считаем разделителями в виде непрерывной последовательности:
      ' ,' fmt
     from dual )
   ) s,
-- пусть количество слов в строке не больше 256 (т.е. 2^8):
   ( select 1 from dual group by cube(1,1,1,1,1,1,1,1) ) n
/*
-- или, как вариант:
   (
    select 1 from all_objects
    where
-- количество слов - как min количество разделителей + 1:
     rownum<=(
      nvl(length('abc 1234, dcvffds 5678, ...'),0)
      -nvl(length(translate('abc 1234, dcvffds 5678, ...',chr(0)||' ,',chr(0))),0)
      )+1
   ) n
*/
  ) z
  where
-- сравниваем слова (целиком), обрамленные пробелами
   instr(' '||translate(t.<ПОЛЕ ВАШЕЙ ТАБЛИЦЫ>,
    ' '||z.fmt,rpad(' ',100,' '))||' ',' '||z.wd||' ')>0
   and z.wd is not null
 )
--------------------------------------------------------------------------------
 and exists
--------------------------------------------------------------------------------
 (
-- вхождение слова из <ПОЛЯ ВАШЕЙ ТАБЛИЦЫ> в строку  '11, 560, 1741, 1234' str2:
  select 1
  from 
  (
   select
    substr(s.nstr,instr(s.nstr,' ',1,rownum)+1,
     instr(s.nstr,' ',1,rownum+1)-instr(s.nstr,' ',1,rownum)-1) wd,
    s.fmt
   from 
   (
    select
     ' '||translate(str,' '||fmt,rpad(' ',100,' '))||' ' nstr,
     fmt
    from ( 
     select
      '11, 560, 1741, 1234' str,
      ' ,' fmt
     from dual )
   ) s,
   ( select 1 from dual group by cube(1,1,1,1,1,1,1,1) ) n
  ) z
  where
   instr(' '||translate(t.<ПОЛЕ ВАШЕЙ ТАБЛИЦЫ>,
    ' '||z.fmt,rpad(' ',100,' '))||' ',' '||z.wd||' ')>0
   and z.wd is not null
 )
--------------------------------------------------------------------------------
-- and <ВАШИ УСЛОВИЯ ПО ВАШЕЙ ТАБЛИЦЕ>
16 май 07, 12:37    [4143631]     Ответить | Цитировать Сообщить модератору
 Re: сравнение содержимого строк  [new]
Stax..
Guest
boles
как посоветуете поступить при таких строках?

какая версия оракля?
......
stax
16 май 07, 16:19    [4145579]     Ответить | Цитировать Сообщить модератору
 Re: сравнение содержимого строк  [new]
N.P.
Member

Откуда:
Сообщений: 2
valerytin

Скажите, а нельзя ли написать процедуру подобную данной, но только сравнивать надо группы, а разделитель между группами перемещается.
Т.е., например, есть
123456789 (на самом деле varchar2)
Надо знать, если во второй строке 1234, затем 2345, затем 3456 и т.д.
18 май 07, 13:55    [4155592]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить