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

Откуда: Самара
Сообщений: 46


К сообщению приложен файл. Размер - 39Kb
10 фев 19, 14:55    [21805666]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите как реализовать?  [new]
Elic
Member

Откуда: 1984. Выбраковка финно-угром продолжается. КЯЗ
Сообщений: 29123
RTFM
10 фев 19, 15:14    [21805675]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите как реализовать?  [new]
skyner81
Member

Откуда: Самара
Сообщений: 46
Elic, тяжело объяснить что это такое. Эта таблица "План пути (точки излома кривых)", где km-Километр точки излома кривой
m-Метр точки излома кривой, r-Радиус. В этой таблице эти точки излома идут друг за другом. А нужно получить КМ и И Начала кривой, КМ и М конца кривой, радиус.
10 фев 19, 15:29    [21805686]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите как реализовать?  [new]
alex-ls
Member

Откуда: Иркутская обл - Пенза - Москва
Сообщений: 6683
опять between с left join
10 фев 19, 15:57    [21805703]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите как реализовать?  [new]
Elic
Member

Откуда: 1984. Выбраковка финно-угром продолжается. КЯЗ
Сообщений: 29123
skyner81
А нужно получить КМ и И Начала кривой, КМ и М конца кривой, радиус.
Ну так и получай. Но только таким же неалгоритмическим способом. Например на гуманитарном форуме.
10 фев 19, 16:03    [21805705]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите как реализовать?  [new]
-2-
Member

Откуда:
Сообщений: 14797
skyner81
km-Километр точки излома кривой
m-Метр точки излома кривой
Типичный пример излома кривой нормализации.
10 фев 19, 16:50    [21805728]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите как реализовать?  [new]
skyner81
Member

Откуда: Самара
Сообщений: 46
alex-ls
опять between с left join


Как использовать between если значение начала и конца в разных строчках?
10 фев 19, 16:59    [21805734]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите как реализовать?  [new]
Elic
Member

Откуда: 1984. Выбраковка финно-угром продолжается. КЯЗ
Сообщений: 29123
skyner81
Как использовать between если значение начала и конца в разных строчках?
Надежда на халяву умирает последней?

+
STFF start_of_group
10 фев 19, 17:13    [21805738]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите как реализовать?  [new]
skyner81
Member

Откуда: Самара
Сообщений: 46
Elic
Надежда на халяву умирает последней?

Да, BETWEEN мне подойдет.
10 фев 19, 17:21    [21805742]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите как реализовать?  [new]
alex-ls
Member

Откуда: Иркутская обл - Пенза - Москва
Сообщений: 6683
skyner81
alex-ls
опять between с left join

Как использовать between если значение начала и конца в разных строчках?

к сожалению я сразу не понял суть задачи
тут скорее self join и lag/lead на форуме куча вопросов по интервалам. Вам надо что-то типа объединить интервалы, а дальше пробовать
10 фев 19, 17:56    [21805757]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите как реализовать?  [new]
Elic
Member

Откуда: 1984. Выбраковка финно-угром продолжается. КЯЗ
Сообщений: 29123
skyner81
Да, BETWEEN мне подойдет.
Глупость человечья безгранична…
10 фев 19, 18:48    [21805775]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите как реализовать?  [new]
ВМоисеев
Member

Откуда: Редкино
Сообщений: 1982
>skyner81, сегодня, 14:55 [21805666]
<Если знаешь, как (1) преобразовать во (2), то закачивай построчно выборку (1) на рабочую станцию и, используя нормальный язык, формируй (2).
10 фев 19, 19:32    [21805785]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите как реализовать?  [new]
skyner81
Member

Откуда: Самара
Сообщений: 46
Elic по вашей подсказке нашел пример, он работает если R равен одному значению у КММ_начала и КММ_конца кривой.
with t (KMM, R) as (
  select 662.065, 1100 from dual union all
  select 662.0774, 1100  from dual union all
  select 662.0841, 1100  from dual union all
  select 662.099, 1100  from dual)

select min (KMM) as KMMN,
       max (KMM) as KMMK,
       R
from (select KMM,R,
sum(strt_grp) over (order by KMM, R ) grp_num
from (select KMM,R,
case when KMM > 1 + max(KMM) over (order by KMM, R rows between unbounded preceding and 1 preceding) then 1 end strt_grp
from t))
group by grp_num,R
order by KMMN


В моем случае у КММ_начала и КММ_конца R=0 и соответственно группируется неправильно
with t (KMM, R) as (
  select 662.065, 0 from dual union all
  select 662.0774, 1100  from dual union all
  select 662.0841, 1100  from dual union all
  select 662.099, 0  from dual)

select min (KMM) as KMMN,
       max (KMM) as KMMK,
       R
from (select KMM,R,
sum(strt_grp) over (order by KMM, R ) grp_num
from (select KMM,R,
case when KMM > 1 + max(KMM) over (order by KMM, R rows between unbounded preceding and 1 preceding) then 1 end strt_grp
from t))
group by grp_num,R
order by KMMN
10 фев 19, 20:10    [21805803]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите как реализовать?  [new]
Elic
Member

Откуда: 1984. Выбраковка финно-угром продолжается. КЯЗ
Сообщений: 29123
skyner81
В моем случае у КММ_начала и КММ_конца R=0 и соответственно группируется неправильно
Невозможно указать на ошибку в реализации неизвестного алгоритма.
10 фев 19, 20:52    [21805821]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите как реализовать?  [new]
skyner81
Member

Откуда: Самара
Сообщений: 46
Elic, чаще всего имеется такая закономерность.

К сообщению приложен файл. Размер - 39Kb
10 фев 19, 22:23    [21805856]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите как реализовать?  [new]
Elic
Member

Откуда: 1984. Выбраковка финно-угром продолжается. КЯЗ
Сообщений: 29123
skyner81
Elic, чаще всего имеется такая закономерность.
Такие закономерности хорошо обрабатываются match_recognize-ом.

Будешь данные давать фотками - получишь словесное описание запроса. Гуманитарий?
10 фев 19, 22:33    [21805867]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите как реализовать?  [new]
skyner81
Member

Откуда: Самара
Сообщений: 46
Elic, также попадаются многорадиусные кривые. Алгоритм такой.

К сообщению приложен файл. Размер - 30Kb
10 фев 19, 22:39    [21805873]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите как реализовать?  [new]
skyner81
Member

Откуда: Самара
Сообщений: 46
Elic, так надо?
with t (KMM, R) as (
  select 662.65, 0 from dual union all
  select 662.774, 1100  from dual union all
  select 662.841, 1100  from dual union all
  select 662.99, 0  from dual union all
  select 663.350, 0  from dual union all  
  select 666.157, 0  from dual union all  
  select 666.234, 690  from dual union all  
  select 667.954, 690  from dual union ALL
  select 668.075, 0  from dual union all  
  select 669.099, 0  from dual union all 
  select 669.110, 800  from dual union all  
  select 669.200, 800  from dual union all    
  select 669.250, 0  from dual union all    
  select 661.060, 0  from dual union all
  select 661.169, 1100  from dual union all
  select 661.534, 1100 from dual union ALL
  select 661.588, 1330 from dual union all
  SELECT 661.640, 1330  from dual union all
  select 661.944, 0  from dual
  )

SELECT * FROM t
10 фев 19, 22:52    [21805882]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите как реализовать?  [new]
Arm79
Member

Откуда: МО, Раменское
Сообщений: 3669
А обязательно решить именно запросом? Судя по приведенным картинкам, предполагается прохождение всей таблицы однократно. По мне - курсор бы вполне сгодился для этого.

Или есть какие-то сверхкритичные требования по быстродействию?
11 фев 19, 00:11    [21805948]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите как реализовать?  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 9529
with d as (
           select 661 km,60 m,0 r from dual union all
           select 661,169,1100 from dual union all
           select 661,534,1100 from dual union all
           select 661,588,1330 from dual union all
           select 661,640,1330 from dual union all
           select 661,944,850 from dual union all
           select 662,324,850 from dual union all
           select 662,427,0 from dual union all
           select 662,650,0 from dual union all
           select 662,774,-1010 from dual union all
           select 662,841,-1010 from dual union all
           select 662,990,0 from dual union all
           select 663,350,0 from dual union all
           select 663,419,0 from dual
          ),
    t1 as (
           select  d.*,
                   case
                     when r = 0 and mod(row_number() over(order by km,m),2) = 1 then 1
                     when r = 0 then 0
                     when lag(r) over(order by km,m) = 0 then 0
                     when lag(r) over(order by km,m) = r then 0
                     else 1
                   end start_of_group,mod(row_number() over(order by km,m),2) x
             from  d
          ),
    t2 as (
           select  t1.*,
                   sum(start_of_group) over(order by km,m) grp
             from  t1
          )
select  case row_number() over(order by grp)
          when 1 then min(km)
          else lag(max(km)) over(order by grp)
        end km_nach,
        case row_number() over(order by grp)
          when 1 then mod(min(km * 1000 + m),1000)
          else lag(mod(max(km * 1000 + m),1000)) over(order by grp)
        end m_nach,
        case mod(max(km * 1000 + m),1000)
          when 0 then max(km) - 1
          else max(km)
        end km_end,
        case mod(max(km * 1000 + m),1000)
          when 0 then 999
          else mod(max(km * 1000 + m),1000) - 1
        end m_end,
        case max(r)
          when 0 then min(r)
          else max(r)
        end r
  from  t2
  group by grp
  having max(abs(r)) != 0
  order by grp
/

   KM_NACH     M_NACH     KM_END      M_END          R
---------- ---------- ---------- ---------- ----------
       661         60        661        533       1100
       661        534        661        639       1330
       661        640        662        426        850
       662        427        662        989      -1010

SQL> 


SY.
11 фев 19, 00:24    [21805952]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите как реализовать?  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 9529
Hе учел впоследней группе вычитать единицу не надо:

with d as (
           select 661 km,60 m,0 r from dual union all
           select 661,169,1100 from dual union all
           select 661,534,1100 from dual union all
           select 661,588,1330 from dual union all
           select 661,640,1330 from dual union all
           select 661,944,850 from dual union all
           select 662,324,850 from dual union all
           select 662,427,0 from dual union all
           select 662,650,0 from dual union all
           select 662,774,-1010 from dual union all
           select 662,841,-1010 from dual union all
           select 662,990,0 from dual union all
           select 663,350,0 from dual union all
           select 663,419,0 from dual
          ),
    t1 as (
           select  d.*,
                   case
                     when r = 0 and mod(row_number() over(order by km,m),2) = 1 then 1
                     when r = 0 then 0
                     when lag(r) over(order by km,m) = 0 then 0
                     when lag(r) over(order by km,m) = r then 0
                     else 1
                   end start_of_group,mod(row_number() over(order by km,m),2) x
             from  d
          ),
    t2 as (
           select  t1.*,
                   sum(start_of_group) over(order by km,m) grp
             from  t1
          )
select  case row_number() over(order by grp)
          when 1 then min(km)
          else lag(max(km)) over(order by grp)
        end km_nach,
        case row_number() over(order by grp)
          when 1 then mod(min(km * 1000 + m),1000)
          else lag(mod(max(km * 1000 + m),1000)) over(order by grp)
        end m_nach,
        case
          when row_number() over(order by grp desc) = 1 then max(km)
          when mod(max(km * 1000 + m),1000) = 0 then max(km) - 1
          else max(km)
        end km_end,
        case
          when row_number() over(order by grp desc) = 1 then mod(max(km * 1000 + m),1000)
          when mod(max(km * 1000 + m),1000) = 0 then 999
          else mod(max(km * 1000 + m),1000) - 1
        end m_end,
        case max(r)
          when 0 then min(r)
          else max(r)
        end r
  from  t2
  group by grp
  having max(abs(r)) != 0
  order by grp
/

   KM_NACH     M_NACH     KM_END      M_END          R
---------- ---------- ---------- ---------- ----------
       661         60        661        533       1100
       661        534        661        639       1330
       661        640        662        426        850
       662        427        662        990      -1010

SQL> 


SY.
11 фев 19, 00:45    [21805955]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите как реализовать?  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 9529
Не учел продoлжение по km/m идет до r = 0:

with d as (
           select 661 km,60 m,0 r from dual union all
           select 661,169,1100 from dual union all
           select 661,534,1100 from dual union all
           select 661,588,1330 from dual union all
           select 661,640,1330 from dual union all
           select 661,944,850 from dual union all
           select 662,324,850 from dual union all
           select 662,427,0 from dual union all
           select 662,650,0 from dual union all
           select 662,774,-1010 from dual union all
           select 662,841,-1010 from dual union all
           select 662,990,0 from dual union all
           select 663,350,0 from dual union all
           select 663,419,0 from dual
          ),
    t1 as (
           select  d.*,
                   mod(row_number() over(order by km,m),2) start_of_group,
                   case
                     when r = 0 and mod(row_number() over(order by km,m),2) = 1 then 1
                     when r = 0 then 0
                     when lag(r) over(order by km,m) = 0 then 0
                     when lag(r) over(order by km,m) = r then 0
                     else 1
                   end start_of_subgroup,mod(row_number() over(order by km,m),2) x
             from  d
          ),
    t2 as (
           select  t1.*,
                   sum(start_of_group) over(order by km,m) grp,
                   sum(start_of_subgroup) over(order by km,m) subgrp
             from  t1
          )
select  case row_number() over(partition by max(grp) order by subgrp)
          when 1 then min(km)
          else lag(max(km)) over(order by subgrp)
        end km_nach,
        case row_number() over(partition by max(grp) order by subgrp)
          when 1 then mod(min(km * 1000 + m),1000)
          else lag(mod(max(km * 1000 + m),1000)) over(order by subgrp)
        end m_nach,
        case
          when row_number() over(order by subgrp desc) = 1 then max(km)
          when mod(max(km * 1000 + m),1000) = 0 then max(km) - 1
          else max(km)
        end km_end,
        case
          when row_number() over(order by subgrp desc) = 1 then mod(max(km * 1000 + m),1000)
          when mod(max(km * 1000 + m),1000) = 0 then 999
          else mod(max(km * 1000 + m),1000) - 1
        end m_end,
        case max(r)
          when 0 then min(r)
          else max(r)
        end r
  from  t2
  group by subgrp
  having max(abs(r)) != 0
  order by subgrp
/

   KM_NACH     M_NACH     KM_END      M_END          R
---------- ---------- ---------- ---------- ----------
       661         60        661        533       1100
       661        588        661        639       1330
       661        944        662        426        850
       662        650        662        990      -1010

SQL> 


SY.
11 фев 19, 01:02    [21805957]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите как реализовать?  [new]
skyner81
Member

Откуда: Самара
Сообщений: 46
SY, Спасибо огромное. В последнем варианте вылезли ошибки. Помогите пожалуйста, я без вас не разберусь.

   KM_NACH     M_NACH     KM_END      M_END          R
---------- ---------- ---------- ---------- ----------
       661        60          661        533        1100
       661        588(534)    661        639        1330
       661        944(640)    662        426(427)   850
       662        650         662        990       -1010
11 фев 19, 07:11    [21806030]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите как реализовать?  [new]
Elic
Member

Откуда: 1984. Выбраковка финно-угром продолжается. КЯЗ
Сообщений: 29123
skyner81
Помогите пожалуйста, я без вас не разберусь.
Нахлебник, думалка не выросла?

Но не расстраивайся сильно.
Соломон из чувства противоречия сломает удочку и насыплет рыбёшки.
Или придёт Станислав и пережуёт всё в гомогенизированную кашицу.
Только ты всё равно останешься "баобабом".
11 фев 19, 07:32    [21806034]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите как реализовать?  [new]
-2-
Member

Откуда:
Сообщений: 14797
match_recognize(
   order by km,m
   measures
      nvl(r0b.km*1000+r0b.m, prev(first(r1.km))*1000+prev(first(r1.m))) mb,
      nvl(r0e.km*1000+r0e.m, last(r1.km)*1000+last(r1.m)-1) me,
      r1.r as r
   pattern
      (r0b{0,1} r1{2} r0e{0,1})
   define
      r0b as r = 0,
      r0e as r = 0,
      r1 as r <> 0
);

        MB         ME          R
---------- ---------- ----------
    661060     661533       1100
    661534     661639       1330
    661640     662427        850
    662650     662990      -1010
11 фев 19, 07:53    [21806039]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить