我如何为具有唯一键的一组记录生成唯一标识符?

问题描述 投票:1回答:3

我有一个看起来像这样的记录集:

| 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 2unique_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表?

sql sql-server tsql sql-update common-table-expression
3个回答
1
投票

[我认为,如果您首先在子查询中选择不同的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

1
投票

代替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;

0
投票

至少在较旧的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;
© www.soinside.com 2019 - 2024. All rights reserved.