如何为一组具有不同键的记录生成唯一标识符?
How do I generate a uniqueidentifier for a set of records with a distinct key?
我有一个如下所示的记录集:
| 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
集生成一个唯一的 ID,其中 unique_id
为空。对于以上内容,我希望 key_sk 2
像 key_sk 3
那样有一个 unique_id
。
我在下面的尝试为每组生成了不同的 uniqueidentifier
。我认为这是因为常见 table 表达式的递归性质:每次加入 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 更简单的方法来执行此操作。我如何为每个不同的 key_sk
生成和更新 history_record
table 一个 uniqueidentifier
?
我认为,如果您首先在子查询中 select distinct key_sk
,然后分配一个新 ID,它应该会按预期工作。这样,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
您可以使用 group by
:
而不是 select distinct
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
键并且您想保留现有值,则可以调整逻辑:
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;
至少在 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;
我有一个如下所示的记录集:
| 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
集生成一个唯一的 ID,其中 unique_id
为空。对于以上内容,我希望 key_sk 2
像 key_sk 3
那样有一个 unique_id
。
我在下面的尝试为每组生成了不同的 uniqueidentifier
。我认为这是因为常见 table 表达式的递归性质:每次加入 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 更简单的方法来执行此操作。我如何为每个不同的 key_sk
生成和更新 history_record
table 一个 uniqueidentifier
?
我认为,如果您首先在子查询中 select distinct key_sk
,然后分配一个新 ID,它应该会按预期工作。这样,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
您可以使用 group by
:
select distinct
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
键并且您想保留现有值,则可以调整逻辑:
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;
至少在 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;