Гость
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Получить предыдущее значение в выборке / 11 сообщений из 11, страница 1 из 1
26.01.2020, 16:24
    #39918830
verter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить предыдущее значение в выборке
Здравствуйте.

На входе есть такая выборка:

Код: plsql
1.
select t.ID, t.val from t order by t.ID



ID val
1 10
2 20
3 0
4 40
5 50

На выходе должно быть следующее:

ID val
1 10
2 20
3 20
4 40
5 50

Если в отсортированной по полю ID выборке в поле val значение = 0, то нужно подставлять в него предыдущее значение поля val
Причём таблица t - это не таблица, а огромный подзапрос, который не хотелось бы много раз повторять.

Как такое можно осуществить?
...
Рейтинг: 0 / 0
26.01.2020, 17:08
    #39918842
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить предыдущее значение в выборке
Код: 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.
with sample_data as (
                     select 1 id,10 val from dual union all
                     select 2,20 from dual union all
                     select 3,0 from dual union all
                     select 4,40 from dual union all
                     select 5,50 from dual
                    )
select  id,
        nvl(new_val,0) val
  from  sample_data
  match_recognize(
                  order by id
                  measures non_zero.val new_val
                  all rows per match
                  pattern(non_zero* zero*)
                  define non_zero as val != 0,
                             zero as val = 0
                 )
/

        ID        VAL
---------- ----------
         1         10
         2         20
         3         20
         4         40
         5         50

SQL>



SY.
...
Рейтинг: 0 / 0
26.01.2020, 17:23
    #39918846
verter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить предыдущее значение в выборке
Уточнение - нужно получить не предыдущее значение val, а предыдущее значение val, которое не равно 0.

И для упрощения можно представить, что t - просто таблица, а не большой подзапрос, это не так важно.
...
Рейтинг: 0 / 0
26.01.2020, 17:27
    #39918848
verter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить предыдущее значение в выборке
SY

match_recognize(
order by id
measures last(non_zero.val) new_val
all rows per match
pattern(non_zero* zero*)
define non_zero as val != 0,
zero as val = 0
)
SY.


Это какой то высший пилотаж из 12-й версии, а у меня 11-я, там нет match_recognize
...
Рейтинг: 0 / 0
26.01.2020, 17:48
    #39918850
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить предыдущее значение в выборке
verter
а у меня 11-я, там нет match_recognize


Я прекрасно помню что у тебя 11G, просто тебе даже после предыдущих ответов упорно не доходит как важно указывать версию особенно когда она не текущая. Tаким образом ты тратишь наше время. И в следующий раз приводи данные в виде CREATE TABLE + INSERT или WITH sample_data AS - форумчане не должны это за тебя делать.

Код: 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.
with sample_data as (
                     select 1 id,10 val from dual union all
                     select 2,20 from dual union all
                     select 3,0 from dual union all
                     select 4,40 from dual union all
                     select 5,50 from dual
                    )
select  id,
        case val
          when 0 then last_value(case val when 0 then null else val end)
                        ignore nulls
                        over(order by id)
          else val
        end val
  from  sample_data
/

        ID        VAL
---------- ----------
         1         10
         2         20
         3         20
         4         40
         5         50

SQL>



Или model если ID идут подряд (model можно и если не подряд но тогда эффективней просто аналитикой):

Код: 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.
with sample_data as (
                     select 1 id,10 val from dual union all
                     select 2,20 from dual union all
                     select 3,0 from dual union all
                     select 4,40 from dual union all
                     select 5,50 from dual
                    )
select  id,
        val
  from  sample_data
  model
    dimension by(id)
    measures(val)
    rules(
          val[any] = case val[cv()]
                       when 0 then nvl(val[cv() - 1],0)
                       else val[cv()]
                     end
         )
/

        ID        VAL
---------- ----------
         1         10
         2         20
         3         20
         4         40
         5         50

SQL>



SY.
...
Рейтинг: 0 / 0
26.01.2020, 18:09
    #39918852
Кобанчег
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить предыдущее значение в выборке
Код: plsql
1.
last_value(nullif(val, 0) ignore nulls) over(order by id)
...
Рейтинг: 0 / 0
26.01.2020, 19:01
    #39918857
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить предыдущее значение в выборке
Кобанчег
Код: plsql
1.
last_value(nullif(val, 0) ignore nulls) over(order by id)



У nullif под капотом тот-же case, но соглашусь буковок меньше. Ну и обернуть в case желательно - незачем выполнять аналитику для строк где val != 0.

SY.
...
Рейтинг: 0 / 0
26.01.2020, 21:29
    #39918872
Кобанчег
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить предыдущее значение в выборке
SY,

Аналитика "выполняется" для всех строк независимо от всяких кейсов.
Рекомендую также подумать как она в принципе работает - что сортируется и сколько раз, как определяется окно по набору строк для каждой результирующей строки и т. д.
Дабы избежать бесед про сферическую аналитику в вакууме можно посмотреть план или sql monitor.
...
Рейтинг: 0 / 0
27.01.2020, 00:59
    #39918921
verter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить предыдущее значение в выборке
Прошу прощения, забыл указать версию оракла и with не сделал, не подумал совсем, в след. раз буду внимательнее.

Спасибо за ответ! Вы используете аналитику, а если совсем по-простому, вот так:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
select t2.val
from t t2
where 
   t2.ID = 
            (select max(t3.ID)
             from t t3
             where t3.ID < t.ID
               and t3.val > 0)



Понимаю, что не оптимально и медленно, но на небольших выборках правильно вроде бы?
...
Рейтинг: 0 / 0
27.01.2020, 07:39
    #39918941
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить предыдущее значение в выборке
verter
Понимаю, что не оптимально и медленно, но на небольших выборках правильно вроде бы?
Простофиля, разве в говнокоде это главное?
...
Рейтинг: 0 / 0
27.01.2020, 09:53
    #39918961
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить предыдущее значение в выборке
verter

Понимаю, что не оптимально и медленно, но на небольших выборках правильно вроде бы?

когда не было аналитики, примерно так и делали (в Кайта есть примерчики)

.....
stax
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Получить предыдущее значение в выборке / 11 сообщений из 11, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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