powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Получить предыдущее значение в выборке
11 сообщений из 11, страница 1 из 1
Получить предыдущее значение в выборке
    #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
Получить предыдущее значение в выборке
    #39918842
Фотография 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
Получить предыдущее значение в выборке
    #39918846
verter
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уточнение - нужно получить не предыдущее значение val, а предыдущее значение val, которое не равно 0.

И для упрощения можно представить, что t - просто таблица, а не большой подзапрос, это не так важно.
...
Рейтинг: 0 / 0
Получить предыдущее значение в выборке
    #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
Получить предыдущее значение в выборке
    #39918850
Фотография 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
Получить предыдущее значение в выборке
    #39918852
Фотография Кобанчег
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plsql
1.
last_value(nullif(val, 0) ignore nulls) over(order by id)
...
Рейтинг: 0 / 0
Получить предыдущее значение в выборке
    #39918857
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кобанчег
Код: plsql
1.
last_value(nullif(val, 0) ignore nulls) over(order by id)



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

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

Аналитика "выполняется" для всех строк независимо от всяких кейсов.
Рекомендую также подумать как она в принципе работает - что сортируется и сколько раз, как определяется окно по набору строк для каждой результирующей строки и т. д.
Дабы избежать бесед про сферическую аналитику в вакууме можно посмотреть план или sql monitor.
...
Рейтинг: 0 / 0
Получить предыдущее значение в выборке
    #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
Получить предыдущее значение в выборке
    #39918941
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
verter
Понимаю, что не оптимально и медленно, но на небольших выборках правильно вроде бы?
Простофиля, разве в говнокоде это главное?
...
Рейтинг: 0 / 0
Получить предыдущее значение в выборке
    #39918961
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
verter

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

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

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


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