Гость
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Выборка самого длинного слова из поля / 16 сообщений из 16, страница 1 из 1
25.02.2021, 19:36
    #40048760
Ольга Семенова
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка самого длинного слова из поля
Добрый день.
Помогите пожалуйста с запросом. В поле хранятся улицы, состоящие как из одного слова так из нескольких.
И мне нужно оставлять лишь самое длинное слово если в названии улицы несколько слов. Разделитель слов в основном ПРОБЕЛ или ТОЧКА

На входе:
Сосновая
8 Марта
им.Павлика Морозова
им.Пушкина
Пифагора
8-й Лучевой
4-ый Северный переулок
героя Леонова
имени Аксакова
им Аксакова

На выходе:
Сосновая
Марта
Морозова
Пушкина
Пифагора
Лучевой
Северный
Леонова
Аксакова
Аксакова
...
Рейтинг: 0 / 0
25.02.2021, 20:13
    #40048768
Vadim Lejnin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка самого длинного слова из поля
Ольга Семенова,

Покажите что Вы пытались сделать, и что у Вас не получилось

Сделайте по крайней мере тестовые данные

памятка:
HOWTO :: Как правильно задавать вопросы
Как мне оформить свое сообщение?
Студентам, желающим помощи

1) Полная постановка задачи (без сокращений)
2) Подготовьте тестовые данные, лучше в виде with
например (не ваш случай):

Код: plsql
1.
2.
3.
4.
5.
6.
with tbl(col1,col2,col3) as (
select 1,'name1',to_date('11.02.1921','DD.MM.YYYY') from dual union all
select 2,'name2',to_date('11.02.1922','DD.MM.YYYY') from dual union all
select 3,'name2',to_date('11.02.1923','DD.MM.YYYY') from dual
)
select col2 from tbl...



3) Покажите что сделали, что получили, без сокращений. ( лучше не в виде screenshot)


4) используйте Тэги, читать код без них неудобно, правильно оформляйте сообщение
...
Рейтинг: 0 / 0
25.02.2021, 20:18
    #40048769
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка самого длинного слова из поля
Говноалгоритм обидит жителей 1-го южного переулка. И не только...
...
Рейтинг: 0 / 0
25.02.2021, 20:30
    #40048770
Ольга Семенова
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка самого длинного слова из поля
Vadim Lejnin,

пример тестовых данных я дала

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
with tbl(street) as (
select 'Сосновая' from dual union all
select '8 Марта' from dual union all
select 'им.Павлика Морозова' from dual union all
select 'им.Пушкина' from dual union all
select 'Пифагора' from dual union all
select '8-й Лучевой' from dual union all
select '4-ый Северный переулок' from dual union all
select 'героя Леонова' from dual union all
select 'имени Аксакова' from dual union all
select 'им Аксакова' from dual
)

select street from tbl



думала сделать через сочетание REGEX_REPLACE как-нибудь
...
Рейтинг: 0 / 0
25.02.2021, 20:34
    #40048772
Ольга Семенова
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка самого длинного слова из поля
Elic
Говноалгоритм обидит жителей 1-го южного переулка. И не только...

согласна. Не всегда самое длинное слово в строке адреса является ключевым
Но я исхожу из наиболее вероятностного алгоритма, т.к. качество исходных данных не позволяет по полной минимизировать расхождения
...
Рейтинг: 0 / 0
25.02.2021, 21:24
    #40048779
Vadim Lejnin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка самого длинного слова из поля
Ольга Семенова,

Очень тупо ( не разработчик я, да и температура)
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
with t1(s1) as (
select 'Сосновая' from dual union all
select '8 Марта' from dual union all
select 'им.Павлика Морозова' from dual union all
select 'им.Пушкина' from dual union all
select 'Пифагора' from dual union all
select '8-й Лучевой' from dual union all
select '4-ый Северный переулок' from dual union all
select 'героя Леонова' from dual union all
select 'имени Аксакова' from dual union all
select 'им Аксакова' from dual
)

-- добавим номер строки для партиции
,t2(i2,s2) as (select rownum,s1 from t1)

-- режем строчку на слова
, t3(i3,l,s3) as (
select  i2,level,regexp_substr(s2,'\w+',1,level)  from t2 connect by level <=regexp_count(s2,'[. -]') + 1
)

-- вычисляем 
,t4(i4,s4,len4, mlen) as (
select i3,s3,length(s3),max(length(s3))  over (partition by i3) from t3
)
select distinct * from t4 where len4=mlen order by i4 
;


        I4 S4
---------- --------------------
         1 Сосновая
         2 Марта
         3 Морозова
         4 Пушкина
         5 Пифагора
         6 Лучевой
         7 Северный
         7 переулок
         8 Леонова
         9 Аксакова
        10 Аксакова
...
Рейтинг: 0 / 0
25.02.2021, 22:43
    #40048795
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка самого длинного слова из поля
Vadim Lejnin
Очень тупо ( не разработчик я
Разработчик сделал бы функцию.
...
Рейтинг: 0 / 0
26.02.2021, 02:42
    #40048813
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка самого длинного слова из поля
Ольга Семенова
Но я исхожу из наиболее вероятностного алгоритма , т.к. качество исходных данных не позволяет по полной минимизировать расхождения

В любом случае, так или иначе, должна быть очистка данных и более строгий и ясный алгоритм. Соответственно, его надо выносить в нормальную "сопровождабельную" функцию.

извращение just4fun
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
with tbl(street) as (
select 'Сосновая' from dual union all
select '8 Марта' from dual union all
select 'им.Павлика Морозова' from dual union all
select 'им.Пушкина' from dual union all
select 'Пифагора' from dual union all
select '8-й Лучевой' from dual union all
select '4-ый Северный переулок' from dual union all
select '7-ый переулок Северный' from dual union all
select 'героя Леонова' from dual union all
select 'имени Аксакова' from dual union all
select 'им Аксакова' from dual union all
select '1 22 333 4444 123456789' from dual
union all
select '1 22 333 123456789 4444' from dual
)

select street 
      ,ltrim(
         regexp_replace(street||' '
          ,'^(\w{1}\W)*(\w{2}\W)*(\w{3}\W)*(\w{4}\W)*(\w{5}\W)*(\w{6}\W)*(\w{7}\W)*(\w{8}\W)*(\w{9}\W)*'
          , '\9 \8 \7 \6 \5 \4 \3 \2 \1'
         )
        ) dummy_sort
      ,regexp_substr(
         ltrim(
           regexp_replace(street||' '
            ,'^(\w{1}\W)*(\w{2}\W)*(\w{3}\W)*(\w{4}\W)*(\w{5}\W)*(\w{6}\W)*(\w{7}\W)*(\w{8}\W)*(\w{9}\W)*'
            , '\9 \8 \7 \6 \5 \4 \3 \2 \1'
           )
         )
        ,'^\w+'
       ) ss
from tbl;

STREET                                   DUMMY_SORT                             SS
---------------------------------------- -------------------------------------- -----------
Сосновая                                 Сосновая                               Сосновая
8 Марта                                  Марта     8                            Марта
им.Павлика Морозова                      Морозова  Павлика      им.             Морозова
им.Пушкина                               Пушкина      им.                       Пушкина
Пифагора                                 Пифагора                               Пифагора
8-й Лучевой                              Лучевой       й                        Лучевой
4-ый Северный переулок                   переулок       ый  4-                  переулок
7-ый переулок Северный                   Северный       ый  7-                  Северный
героя Леонова                            Леонова   героя                        Леонова
имени Аксакова                           Аксакова    имени                      Аксакова
им Аксакова                              Аксакова       им                      Аксакова
1 22 333 4444 123456789                  123456789      4444  333  22  1        123456789
1 22 333 123456789 4444                  123456789       333  22  1 4444        123456789


можно было сделать монстра и для большей макс.длины слова, но лень заворачивать...
...
Рейтинг: 0 / 0
26.02.2021, 08:43
    #40048825
Ольга Семенова
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка самого длинного слова из поля
Vadim Lejnin , Sayan Malakshinov , спасибо огромное.
Классно с регуляркой вышло. Буду тестировать
...
Рейтинг: 0 / 0
26.02.2021, 09:31
    #40048831
Ольга Семенова
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка самого длинного слова из поля
Sayan Malakshinov , а как ваш алгоритм через регулярку доработать до длины слова в 20 символов ?

думала по аналогии сделать

Код: plsql
1.
2.
3.
4.
5.
         regexp_replace(street||' '
          ,'^(\w{1}\W)*(\w{2}\W)*(\w{3}\W)*(\w{4}\W)*(\w{5}\W)*(\w{6}\W)*(\w{7}\W)*(\w{8}\W)*(\w{9}\W)*(\w{10}\W)*(\w{11}\W)*(\w{12}\W)*(\w{13}\W)*(\w{14}\W)*(\w{15}\W)*(\w{16}\W)*(\w{17}\W)*(\w{18}\W)*(\w{19}\W)*(\w{20}\W)*'
          , '\20 \19 \18 \17 \16 \15 \14 \13 \12 \11 \10 \9 \8 \7 \6 \5 \4 \3 \2 \1'
         )
        )



но получается ерунда (((
...
Рейтинг: 0 / 0
26.02.2021, 13:05
    #40048917
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка самого длинного слова из поля
Ольга Семенова
Sayan Malakshinov , а как ваш алгоритм через регулярку доработать до длины слова в 20 символов ?
...
но получается ерунда (((
да это просто демонстрация возможности. На самом деле не надо такое использовать в сопровождаемом коде...

зы. А принципиально
авторreplace_string can be of any of the datatypes CHAR, VARCHAR2, NCHAR, NVARCHAR2, CLOB, or NCLOB. If replace_string is a CLOB or NCLOB, then Oracle truncates replace_string to 32K. The replace_string can contain up to 500 backreferences to subexpressions in the form \n, where n is a number from 1 to 9 .
так что подход тот же самый, только поочередно + вложенно обрабатывать по 9 штук:
Код: plsql
1.
2.
3.
4.
         regexp_replace(street||' '
          ,'^(\w{9}\W)*(\w{10}\W)*(\w{11}\W)*(\w{12}\W)*(\w{13}\W)*(\w{14}\W)*(\w{15}\W)*(\w{16}\W)*(\w{17}\W)*'
          , '\9 \8 \7 \6 \5 \4 \3 \2 \1'
         )
...
Рейтинг: 0 / 0
27.02.2021, 15:01
    #40049203
qlost
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка самого длинного слова из поля
Чёт тоже решил заморочиться
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
WITH
t0(street) AS (
select 'Сосновая' from dual union all
select '8 Марта' from dual union all
select 'им.Павлика Морозова' from dual union all
select 'им.Пушкина' from dual union all
select 'Пифагора' from dual union all
select '8-й Лучевой' from dual union all
select '4-ый Северный переулок' from dual union all
select '7-ый переулок Северный' from dual union all
select 'героя Леонова' from dual union all
select 'имени Аксакова' from dual union all
select 'им Аксакова' from dual union all
select '1 22 333 4444 123456789' from dual union all
select '1 22 333 123456789 4444' from dual
),
t1 AS (SELECT ROWNUM AS rn, street FROM t0),
t2 AS (
SELECT t1.rn, t1.street, x.subs
     , LENGTH(x.subs) AS LEN
     , MAX(LENGTH(x.subs)) OVER (PARTITION BY t1.rn) AS maxlen
     , ROW_NUMBER() OVER (PARTITION BY t1.rn ORDER BY NULL) AS rn2
  FROM t1, XMLTABLE(
    'if (fn:matches($X,"[. ]")) then ora:tokenize($X,"[. ]") else $X'
    PASSING t1.street AS X
    COLUMNS subs VARCHAR2(4000) PATH '.'
  ) x
 WHERE x.subs IS NOT NULL
)
SELECT rn, MAX(subs) KEEP (DENSE_RANK FIRST ORDER BY LEN DESC, rn2) AS street
  FROM t2
 GROUP BY rn
 ORDER BY rn;


RNSTREET1Сосновая2Марта3Морозова4Пушкина5Пифагора6Лучевой7Северный8переулок9Леонова10Аксакова11Аксакова1212345678913123456789
...
Рейтинг: 0 / 0
27.02.2021, 17:05
    #40049220
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка самого длинного слова из поля
Ольга Семенова

думала сделать через сочетание REGEX_REPLACE как-нибудь


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
WITH FUNCTION F_EXEC(
                     P_EXPR VARCHAR2
                    )
       RETURN VARCHAR2
       IS
           V_RES VARCHAR2(4000);
       BEGIN
           EXECUTE IMMEDIATE 'BEGIN :V_RES := ' || P_EXPR || '; END;'
             USING OUT V_RES;
           RETURN V_RES;
       END;
T(STREET)
  AS (
      select 'Sosnovaja' from dual union all
      select '8 Marta' from dual union all
      select 'im.Pavlika Morozova' from dual union all
      select 'im.Pushkina' from dual union all
      select 'Pifagora' from dual union all
      select '8-j Luchevoj' from dual union all
      select '4-yj Severnyj pereulok' from dual union all
      select '7-yj pereulok Severnyj' from dual union all
      select 'geroja Leonova' from dual union all
      select 'imeni Aksakova' from dual union all
      select 'im Aksakova' from dual union all
      select '1 22 333 4444 123456789' from dual union all
      select '1 22 333 123456789 4444' from dual
     )
SELECT  SUBSTR(
               F_EXEC(
                      'GREATEST(' ||
                      REGEXP_REPLACE(
                                     REGEXP_REPLACE(
                                                    STREET,
                                                    '([^ \.]+)',
                                                    'LPAD(LENGTH(''\1''),10)||''\1'''
                                                   ),
                                     '[. ]+',
                                     ' , '
                                    ) ||
                      ')'
                     ),
              11
             ) STREET
  FROM  T
/
STREET
------------------------------
Sosnovaja
Marta
Morozova
Pushkina
Pifagora
Luchevoj
pereulok
pereulok
Leonova
Aksakova
Aksakova
123456789
123456789

13 rows selected.

SQL>



Но как правильно заметил Elic "Говноалгоритм обидит жителей 1-го южного переулка. И не только..."

SY.
...
Рейтинг: 0 / 0
28.02.2021, 15:35
    #40049360
Ольга Семенова
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка самого длинного слова из поля
qlost , SY , спасибо вам!!!
Работает шустро.
...
Рейтинг: 0 / 0
28.02.2021, 16:31
    #40049366
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка самого длинного слова из поля
Ольга Семенова
qlost , SY , спасибо вам!!!
Работает шустро.


XML решение куда проще чем у qlost:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
WITH T(STREET)
  AS (
      select 'Sosnovaja' from dual union all
      select '8 Marta' from dual union all
      select 'im.Pavlika Morozova' from dual union all
      select 'im.Pushkina' from dual union all
      select 'Pifagora' from dual union all
      select '8-j Luchevoj' from dual union all
      select '4-yj Severnyj pereulok' from dual union all
      select '7-yj pereulok Severnyj' from dual union all
      select 'geroja Leonova' from dual union all
      select 'imeni Aksakova' from dual union all
      select 'im Aksakova' from dual union all
      select '1 22 333 4444 123456789' from dual union all
      select '1 22 333 123456789 4444' from dual
     )
SELECT  T.STREET,
        X.SUB_STREET
  FROM  T,
        XMLTABLE(
                 'if (fn:matches($street,"[. ]"))
                    then
                      for $s in ora:tokenize($street,"[. ]")
                        order by fn:string-length($s) descending
                        return $s
                    else
                      $street'
                 PASSING T.STREET AS "street"
                 COLUMNS
                   SUB_STREET VARCHAR2(4000) PATH '.',
                   N FOR ORDINALITY
                ) X
  WHERE X.N = 1
/

STREET                         SUB_STREET
------------------------------ ------------------------------
Sosnovaja                      Sosnovaja
8 Marta                        Marta
im.Pavlika Morozova            Morozova
im.Pushkina                    Pushkina
Pifagora                       Pifagora
8-j Luchevoj                   Luchevoj
4-yj Severnyj pereulok         Severnyj
7-yj pereulok Severnyj         pereulok
geroja Leonova                 Leonova
imeni Aksakova                 Aksakova
im Aksakova                    Aksakova
1 22 333 4444 123456789        123456789
1 22 333 123456789 4444        123456789

13 rows selected.

SQL>



SY.
...
Рейтинг: 0 / 0
28.02.2021, 16:34
    #40049368
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка самого длинного слова из поля
Ольга Семенова
Работает шустро.
Антоним к "все мужики сво…" сама подберёшь?
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Выборка самого длинного слова из поля / 16 сообщений из 16, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]