Генерация последовательности с одинаковыми значениями для группы - PullRequest
0 голосов
/ 26 февраля 2019

Ниже приведены значения в таблице:

|  Val1  |  
| 201900 |  
| 201910 |  
| 201920 |
| 201930 |
| 201901 |
| 201911 |
| 201921 |  
| 201931 |  
| 201902 |  
| 201912 | 
| 201922 | 
| 201932 |  

Последняя цифра - это уровень (0,1,2, ..) в 2019 году. Вторая последняя цифра - это идентификатор, которыйдействует на определенную дату.Значение 0 действительно в течение 3 месяцев в 201900 году, через 3 месяца будет добавлено новое значение, которое будет 201910. Например, для уровня 0 и 1 будут две разные активные записи, которые являются 201900 и 201901 в данный момент времени.Я хочу назначить один и тот же порядковый номер для этих двух записей.Вывод должен выглядеть примерно так:

|  Val1  | Seq |  
| 201900 |  1  |
| 201910 |  2  |
| 201920 |  3  |
| 201930 |  4  |
| 201901 |  1  | 
| 201911 |  2  |
| 201921 |  3  |
| 201931 |  4  |
| 201902 |  1  |
| 201912 |  2  |
| 201922 |  3  |
| 201932 |  4  |

Я использую облако снежинки DW, но синтаксис Oracle должен работать нормально.Однако у Snowflake нет опции CurrVal в последовательности.
Я пытаюсь это сделать, но не работает:

> (SUBSTRING(Val1,6,1)=0 OR SUBSTRING(Val1,6,1)=1
> OR SUBSTRING(Val1,6,1)=2 OR
> SUBSTRING(Val1,6,1)=3 OR SUBSTRING(Val1,6,1)=4 
>     OR SUBSTRING(Val1,6,1)=5) THEN (SELECT  s.nextval FROM table(getnextval(test_seq)) s)

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

Если тип данных столбца VAL1 НОМЕР, то почему бы не сделать это следующим образом?

with test (val1) as
  (select 201900 from dual union all
   select 201910 from dual union all
   select 201920 from dual union all
   select 201930 from dual union all
   select 201901 from dual union all
   select 201911 from dual union all
   select 201921 from dual union all
   select 201931 from dual union all
   select 201902 from dual union all
   select 201912 from dual union all
   select 201922 from dual union all
   select 201932 from dual)
select val1,
  row_number() over (partition by trunc(val1/100), mod(val1, 10)
                     order by mod(trunc(val1/10), 10)) seq
from test;

Вывод:

+--------+-----+
|  VAL1  | SEQ |
+--------+-----+
| 201900 |   1 |
| 201910 |   2 |
| 201920 |   3 |
| 201930 |   4 |
| 201901 |   1 |
| 201911 |   2 |
| 201921 |   3 |
| 201931 |   4 |
| 201902 |   1 |
| 201912 |   2 |
| 201922 |   3 |
| 201932 |   4 |
+--------+-----+

Обновить# 1:

То, о чем вы спрашиваете, это OUTER JOIN.Но, может быть, вам нужна функциональность аналитической функции LAG?Я также думаю, что нет необходимости упорядочивать по идентификатору, потому что после разбиения по году и уровню значение столбца VAL1 дает нам естественное упорядочение в результирующих разделах.

with
  test (val1) as
  (select 201900 from dual union all
   select 201910 from dual union all
   select 201920 from dual union all
   select 201930 from dual union all
   select 201901 from dual union all
   select 201911 from dual union all
   select 201921 from dual union all
   select 201931 from dual union all
   select 201902 from dual union all
   select 201912 from dual union all
   select 201922 from dual union all
   select 201932 from dual),
  t as
  (select
     test.*,
     row_number() over (partition by trunc(val1/100), mod(val1, 10)
                        order by val1) as seq
   from test)
select
  a.*, b.val1 as prev_value
from t a
left outer join t b
  on trunc(a.val1/100) = trunc(b.val1/100) and
     mod(a.val1, 10) = mod(b.val1, 10) and
     a.seq = b.seq + 1
order by trunc(a.val1/100), mod(a.val1, 10), a.val1;

Вывод:

+--------+-----+------------+
|  VAL1  | SEQ | PREV_VALUE |
+--------+-----+------------+
| 201900 |   1 |            |
| 201910 |   2 |     201900 |
| 201920 |   3 |     201910 |
| 201930 |   4 |     201920 |
| 201901 |   1 |            |
| 201911 |   2 |     201901 |
| 201921 |   3 |     201911 |
| 201931 |   4 |     201921 |
| 201902 |   1 |            |
| 201912 |   2 |     201902 |
| 201922 |   3 |     201912 |
| 201932 |   4 |     201922 |
+--------+-----+------------+

Аналитическая функция LAG:

with test (val1) as
  (select 201900 from dual union all
   select 201910 from dual union all
   select 201920 from dual union all
   select 201930 from dual union all
   select 201901 from dual union all
   select 201911 from dual union all
   select 201921 from dual union all
   select 201931 from dual union all
   select 201902 from dual union all
   select 201912 from dual union all
   select 201922 from dual union all
   select 201932 from dual)
select val1,
  lag(val1) over (partition by trunc(val1/100), mod(val1, 10)
                  order by val1) as prev_value
from test;

Выход:

+--------+------------+
|  VAL1  | PREV_VALUE |
+--------+------------+
| 201900 |            |
| 201910 |     201900 |
| 201920 |     201910 |
| 201930 |     201920 |
| 201901 |            |
| 201911 |     201901 |
| 201921 |     201911 |
| 201931 |     201921 |
| 201902 |            |
| 201912 |     201902 |
| 201922 |     201912 |
| 201932 |     201922 |
+--------+------------+

Протестируйте его в режиме онлайн с дБ<> скрипка .

0 голосов
/ 27 февраля 2019

Как то так?Полезной частью являются строки 16-17.

SQL> with test (val1) as
  2    (select 201900 from dual union all
  3     select 201910 from dual union all
  4     select 201920 from dual union all
  5     select 201930 from dual union all
  6     select 201901 from dual union all
  7     select 201911 from dual union all
  8     select 201921 from dual union all
  9     select 201931 from dual union all
 10     select 201902 from dual union all
 11     select 201912 from dual union all
 12     select 201922 from dual union all
 13     select 201932 from dual
 14    )
 15  select val1,
 16    row_number() over (partition by substr(val1, 1, 4), substr(val1, -1)
 17                       order by substr(val1, 5, 1)) seq
 18  from test;

      VAL1        SEQ
---------- ----------
    201900          1
    201910          2
    201920          3
    201930          4
    201901          1
    201911          2
    201921          3
    201931          4
    201902          1
    201912          2
    201922          3
    201932          4

12 rows selected.

SQL>
...