我有一个看起来像这样的记录集:
| 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
集生成一个唯一ID。对于上述情况,我希望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
表?
[我认为,如果您首先在子查询中选择不同的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
代替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
键,并且您想保留现有值,则可以调整逻辑:
with update_id_cte as (
select hr.key_sk, 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;