Добавить столбец позиции на основе порядка - Oracle - PullRequest
0 голосов
/ 19 мая 2019

У меня есть эта таблица со следующими записями:

table1

id      ele_id_1    ele_val      ele_id_2       
1       2           123          1  
1       1           abc          1  
1       4           xyz          2  
1       4           456          1  
2       5           22           1
2       4           344          1  
2       3           6            1  
2       2           Test Name    1          
2       1           Hello        1  

Я пытаюсь добавить позицию для каждого id, когда ele_id_1 и ele_id_2 упорядочены поASC.

Вот вывод:

id      ele_id_1    ele_val      ele_id_2       position
1       2           123          1              2
1       1           abc          1              1
1       4           xyz          2              4
1       4           456          1              3
2       5           22           1              5
2       4           344          1              4
2       3           6            1              3
2       2           Test Name    1              2
2       1           Hello        1              1

У меня есть 34 миллиона строк в таблице1, поэтому я хотел бы использовать эффективный способ сделать это.

Любая идеяо том, как я могу добавить положение со значениями?

1 Ответ

3 голосов
/ 19 мая 2019

Я думаю, вы хотите row_number() использовать так:

select row_number() over (partition by id
                          order by ele_id_1, ele_id_2
                         ) as position

Oracle может использовать индекс для этого на (id, ele_id_1, ele_id_2).

Следует отметить, что для вашего примера данные order by ele_id_1, ele_id_2 и order by ele_id_2, ele_id_1 дают одинаковый результат. Ваш вопрос предполагает, что вы хотите первый.

Итак, вы получите

id      ele_id_1    ele_val      ele_id_2       position
1       1           123          2          2
1       1           abc          1          1
1       4           xyz          2          4
1       4           456          1          3

Вместо:

id      ele_id_1    ele_val      ele_id_2       position
1       1           123          2          3
1       1           abc          1          1
1       4           xyz          2          4
1       4           456          1          2

EDIT:

Если вы хотите обновить данные, тогда merge, вероятно, лучший подход.

MERGE INTO <yourtable> dest
   USING (select t.*,
                 row_number() over (partition by id
                                    order by ele_id_1, ele_id_2
                                   ) as new_position
          from <yourtable> t
         ) src
         ON dest.id = src.id AND
            dest.ele_id_1 = src.ele_id_1 AND
            dest.ele_id_2 = src.ele_id_2          
   WHEN MATCHED THEN UPDATE
        SET desc.postition = src.new_position;

Обратите внимание, что обновление всех строк в таблице является дорогостоящей операцией. Усечение таблицы и ее воссоздание может быть проще:

create table temp_t as 
    select t.*, 
           row_number() over (partition by id
                              order by ele_id_1, ele_id_2
                             ) as new_position
    from t;

truncate table t;

insert into t ( . . . )
    select . . .  -- all columns but position
    from temp_t;

Однако будьте очень осторожны, если вы урежете таблицу. Обязательно сначала сделайте резервную копию!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...