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

Откуда:
Сообщений: 233
Здравствуйте. В соседней ветке ребята подсказали как сделать сложный поиск по дереву в mysql с денормализацией. Стало интересно можно ли так сделать в Oracle сохраняя данные в нормальной форме.

Есть дерево Мест:
СНГ
      |_Россия
            |_Московская область
                  |_Москва
      |_Беларусь
            |_Минская область
                  |_Минск


Можно ли по имени "СНГ, Московская область", выбрать всех детей. Города могут повторятся в разных ветках, поиск может быть не только из 2 элементов, и в запросе имена могут идти с пропусками веток как например в примере пропущено "Россия".
17 окт 13, 16:46    [14986725]     Ответить | Цитировать Сообщить модератору
 Re: Сложный поиск в дереве  [new]
Vint
Member

Откуда: Москва
Сообщений: 4564
z3r9,
это можно сделать даже likeом
17 окт 13, 16:55    [14986815]     Ответить | Цитировать Сообщить модератору
 Re: Сложный поиск в дереве  [new]
K790
Member

Откуда:
Сообщений: 633
z3r9,

автор
Города могут повторятся в разных ветках

т.е. на данном примере можно, например, добавить в Московскую обл. Минск, и по запросу имени Минск, в результате получаем всех чайлдов СНГ, или как ?
17 окт 13, 17:00    [14986858]     Ответить | Цитировать Сообщить модератору
 Re: Сложный поиск в дереве  [new]
z3r9
Member

Откуда:
Сообщений: 233
автор
т.е. на данном примере можно, например, добавить в Московскую обл. Минск, и по запросу имени Минск, в результате получаем всех чайлдов СНГ, или как ?


Не совсем понял. Добавляем в Московскую обл. Минск. И ищем например по запросу "СНГ Минск", тогда должно найти:
1. /СНГ/Россия/Московская область/Минск
2. /СНГ/Беларусь/Минская область/Минск
17 окт 13, 17:24    [14987025]     Ответить | Цитировать Сообщить модератору
 Re: Сложный поиск в дереве  [new]
как_то_так
Guest
+
with t(n,
n_par,
text) as
 (select 1, NULL, 'СНГ'
    from dual
  union all
  select 2, 1, 'Россия'
    from dual
  union all
  select 3, 2, 'Московская область'
    from dual
  union all
  select 4, 3, 'Москва'
    from dual
  union all
  select 5, 1, 'Беларусь'
    from dual
  union all
  select 6, 5, 'Минская область'
    from dual
  union all
  select 7, 6, 'Минск'
    from dual
  union all
  select 8, nuLL, 'Европа'
    from dual
  union all
  select 9, 8, 'Голладия'
    from dual
  union all
  select 10, 9, 'Амстердам'
    from dual
  union all
  select 11, 8, 'Чехия' from dual)
select lpad(' ', (level - 1) * 10, ' ') || text
  from t
 start with text='СНГ'
connect by prior n = n_par
17 окт 13, 17:57    [14987221]     Ответить | Цитировать Сообщить модератору
 Re: Сложный поиск в дереве  [new]
z3r9
Member

Откуда:
Сообщений: 233
как_то_так , вы же просто выбрали СНГ. А нужно к примеру выбрать ветвь Минск у которой есть прародитель СНГ. Потому как городов с одноименным названием может быть много.

Есть дерево:
1. /СНГ/Россия/Московская область/Минск
2. /СНГ/Беларусь/Минская область/Минск

По запросу "СНГ Минск":
1. /СНГ/Россия/Московская область/Минск
2. /СНГ/Беларусь/Минская область/Минск

По запросу "СНГ Беларусь Минск":
2. /СНГ/Беларусь/Минская область/Минск
17 окт 13, 19:42    [14987643]     Ответить | Цитировать Сообщить модератору
 Re: Сложный поиск в дереве  [new]
sys_connect_белорусский_путь
Guest
z3r9,

сложным твой поиск является, потому что ты не способен четко описать условия задачи.
пока нет причин игнорировать предложенный лайк
17 окт 13, 19:57    [14987694]     Ответить | Цитировать Сообщить модератору
 Re: Сложный поиск в дереве  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10045
SCOTT@orcl > variable search varchar2(4000)
SCOTT@orcl > exec :search := 'SNG,Minsk';

PL/SQL procedure successfully completed.

SCOTT@orcl > with t as (
  2             select 1 id, NULL parent_id, 'SNG' name from dual union all
  3             select 2, 1, 'Russia' from dual union all
  4             select 3, 2, 'Moscow region' from dual union all
  5             select 4, 3, 'Moscow' from dual union all
  6             select 5, 1, 'Belarus' from dual union all
  7             select 6, 5, 'Minsk region' from dual union all
  8             select 7, 6, 'Minsk' from dual union all
  9             select 8, nuLL, 'Europe' from dual union all
 10             select 9, 8, 'Holland' from dual union all
 11             select 10, 9, 'Amsterdam' from dual union all
 12             select 11, 8, 'Czech Republic' from dual union all
 13             select 12, 3, 'Minsk' from dual
 14            ),
 15       h as (
 16             select  ',,' || reverse(sys_connect_by_path(reverse(name),',,')) path
 17               from  t
 18               where connect_by_isleaf = 1
 19               start with name = substr(:search,instr(:search,',',-1) + 1)
 20               connect by prior parent_id = id
 21            )
 22  select  *
 23    from  h
 24    where path like '%,' || replace(:search,',',',%,') || ',%'
 25  /

PATH
---------------------------------------------------------------------------------------
,,SNG,,Belarus,,Minsk region,,Minsk,,
,,SNG,,Russia,,Moscow region,,Minsk,,

SCOTT@orcl > exec :search := 'SNG,Belarus,Minsk';

PL/SQL procedure successfully completed.

SCOTT@orcl > with t as (
  2             select 1 id, NULL parent_id, 'SNG' name from dual union all
  3             select 2, 1, 'Russia' from dual union all
  4             select 3, 2, 'Moscow region' from dual union all
  5             select 4, 3, 'Moscow' from dual union all
  6             select 5, 1, 'Belarus' from dual union all
  7             select 6, 5, 'Minsk region' from dual union all
  8             select 7, 6, 'Minsk' from dual union all
  9             select 8, nuLL, 'Europe' from dual union all
 10             select 9, 8, 'Holland' from dual union all
 11             select 10, 9, 'Amsterdam' from dual union all
 12             select 11, 8, 'Czech Republic' from dual union all
 13             select 12, 3, 'Minsk' from dual
 14            ),
 15       h as (
 16             select  ',,' || reverse(sys_connect_by_path(reverse(name),',,')) path
 17               from  t
 18               where connect_by_isleaf = 1
 19               start with name = substr(:search,instr(:search,',',-1) + 1)
 20               connect by prior parent_id = id
 21            )
 22  select  *
 23    from  h
 24    where path like '%,' || replace(:search,',',',%,') || ',%'
 25  /

PATH
---------------------------------------------------------------------------------------
,,SNG,,Belarus,,Minsk region,,Minsk,,

SCOTT@orcl > 


SY.
17 окт 13, 20:57    [14987860]     Ответить | Цитировать Сообщить модератору
 Re: Сложный поиск в дереве  [new]
z3r9
Member

Откуда:
Сообщений: 233
sys_connect_белорусский_путь, спасибо, очень ценное замечание и действительно так оно и есть.

Vint и SY, единственный выход который я видел это искать в Path но для меня это решение показалось очень плохим. Я как-то не подумал что можно сразу найти в дереве населенные пункты а потом найти в пути соответствие.

Спасибо всем большое за помощь!
17 окт 13, 22:37    [14988268]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить