Как мне создать уникальный идентификатор для набора записей с отдельным ключом? - PullRequest
1 голос
/ 30 мая 2020

У меня есть набор записей, который выглядит следующим образом:

| key_sk | unique_id                            |
|--------|--------------------------------------|
| 2      | null                                 |
| 2      | null                                 |
| 3      | 83a1c90b-e58d-4db4-b438-a79edfb28e60 |
| 3      | 83a1c90b-e58d-4db4-b438-a79edfb28e60 |
| 4      | 4ce66783-0b84-4e8a-a0de-c3284e4d9cd0 |
| 5      | null                                 |

Я хотел бы создать уникальный идентификатор для каждого уникального набора key_sk, где unique_id имеет значение null. Для приведенного выше я хотел бы, чтобы key_sk 2 имел один unique_id, как key_sk 3.

Моя попытка ниже генерировала разные uniqueidentifier для каждого набора. Я думаю, это из-за рекурсивной природы общих табличных выражений: каждое присоединение к CTE вызывает вызов NEWID().

;with update_id_cte as
(
  select distinct hr.key_sk
        ,NEWID() as gened_unique_id
    from history_record hr
   where hr.unique_id is null
)
update hr
   set hr.unique_id = cte.gened_unique_id
  from history_record hr
       join update_id_cte cte
         on hr.key_sk = cte.key_sk

Вероятно, для этого есть более простой способ, чем использование CTE. Как я могу сгенерировать и обновить таблицу history_record одним uniqueidentifier для каждого отдельного key_sk?

Ответы [ 3 ]

1 голос
/ 30 мая 2020

Вместо select distinct вы можете использовать group by:

with update_id_cte as (
       select hr.key_sk, NEWID() as gened_unique_id
       from history_record hr
       where hr.unique_id is null
       group by hr.key_sk
      )
update hr
   set hr.unique_id = cte.gened_unique_id
   from history_record hr join
        update_id_cte cte
        on hr.key_sk = cte.key_sk;

Если возможно, что некоторые значения key_sk имеют как NULL, так и не- NULL ключи И вы хотите чтобы сохранить существующие значения, вы можете настроить лог c:

with update_id_cte as (
       select hr.key_sk, coalesce(max(hr.unique_id), NEWID()) as gened_unique_id
       from history_record hr
       group by hr.key_sk
      )
update hr
   set hr.unique_id = cte.gened_unique_id
   from history_record hr join
        update_id_cte cte
        on hr.key_sk = cte.key_sk
   where hr.unique_id is null;
1 голос
/ 30 мая 2020

По крайней мере, в более старой версии MySQL это может быть проблемой, поскольку вы проверяете и хотите проверить тот же столбец, один из способов сделать это - использовать временные таблицы.

Это не один запрос а скорее часть хранимой процедуры, но если вы собираетесь сделать это только один раз, вы можете просто запустить ее.

CREATE TEMPORARY TABLE IF NOT EXISTS tmp
select distinct hr.key_sk ,NEWID() as gened_unique_id
from history_record hr
where hr.unique_id is null;

update hr
set hr.unique_id = tmp.gened_unique_id
from history_record hr
inner join tmp on hr.key_sk = tmp.key_sk;
1 голос
/ 30 мая 2020

Я думаю, что он должен работать так, как вы ожидаете, если вы сначала выберете отдельный key_sk в подзапросе, а затем назначите новый идентификатор. Таким образом, newid() вызывается только один раз для отдельной цели key_sk:

with update_id_cte as (
    select key_sk, newid() as gened_unique_id
    from (select distinct key_sk from history_record where unique_id is null) t
)
update hr
set hr.unique_id = cte.gened_unique_id
from history_record hr
inner join update_id_cte cte on hr.key_sk = cte.key_sk
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...