简体   繁体   English

使用 SQL 服务器中另一个表的 id 更新现有表的新外键列

[英]Update new foreign key column of existing table with ids from another table in SQL Server

I have an existing table to which I have added a new column which is supposed to hold the Id of a record in another (new) table.我有一个现有的表,我在其中添加了一个新列,该列应该保存另一个(新)表中记录的 ID。

Simplified structure is sort of like this:简化的结构是这样的:

Customer table客户表

[CustomerId] [GroupId] [LicenceId]  <-- new column

Licence table <-- new table许可证表 <-- 新表

[LicenceId] [GroupId]

The Licence table has a certain number of licences per group than can be assigned to customers in that same group.许可证表中的每个组具有一定数量的许可证,这些许可证可以分配给同一组中的客户。 There are multiple groups, and each group has a variable number of customers and licences.有多个组,每个组都有可变数量的客户和许可证。 So say there are 100 licences available for group 1 and there are 50 customers in group 1, so each can get a license.假设第 1 组有 100 个可用许可证,第 1 组有 50 个客户,所以每个人都可以获得一个许可证。 There are never more customers than there are licences.客户数量永远不会超过许可证数量。

Sample样本

Customer
[CustomerId] [GroupId] [LicenceId]
 1            1         NULL
 2            1         NULL
 3            1         NULL
 4            1         NULL
 5            2         NULL
 6            2         NULL
 7            2         NULL
 8            3         NULL
 9            3         NULL

Licence
[LicenceId] [GroupId]
 1            1
 2            1
 3            1
 4            1
 5            1
 6            1
 7            2
 8            2
 9            2
 10           2
 11           2
 12           3
 13           3
 14           3
 15           3
 16           3
 17           3

Desired outcome

Customer
[CustomerId] [GroupId] [LicenceId]
 1            1         1
 2            1         2
 3            1         3
 4            1         4
 5            2         7
 6            2         8
 7            2         9
 8            3         12
 9            3         13

So now I have to do this one time update to give every customer a licence and I have no idea how to go about it.所以现在我必须做这个一次更新给每个客户一个许可证,我不知道如何 go 关于它。

I'm not allowed to use a cursor.我不允许使用 cursor。 I can't seem to do a MERGE UPDATE, because joining the Customer to the Licence table by GroupId will result in multiple hits.我似乎无法进行合并更新,因为通过 GroupId 将客户加入许可证表会导致多次点击。

How do I assign each customer the next available LicenceId within their group in one query?如何在一个查询中为每个客户分配其组内的下一个可用 LicenceId? Is this even possible?这甚至可能吗?

You can use window functions:您可以使用 window 函数:

with c as (
      select c.*, row_number() over (partition by groupid order by newid()) as seqnum
      from customers c
     ), 
     l as (
      select l.*, row_number() over (partition by groupid order by newid()) as seqnum
      from licenses c
     )
update c
    set c.licenceid = l.licenseid
    from c join
         l
         on c.seqnum = l.seqnum and c.groupid = l.groupid;

This assigns the licenses randomly .这会随机分配许可证。 That is really just for fun.那真的只是为了好玩。 The most efficient method is to use:最有效的方法是使用:

row_number() over (partition by groupid order by (select null)) as seqnum

SQL Server often avoids an additional sort operation in this case. SQL 服务器在这种情况下通常会避免额外的排序操作。

But you might want to order them by something else -- for instance by the ordering of the customer ids, or by some date column, or something else.但是您可能希望通过其他方式对它们进行排序——例如通过客户 ID 的排序、某个日期列或其他方式。

Gordon has put it very well in his answer.戈登在他的回答中说得很好。 Let me break it down into simpler steps for you.让我把它分解成更简单的步骤。

Step 1. Use the ROW_NUMBER() function to assign a SeqNum to the Customers.步骤 1. 使用 ROW_NUMBER() function 将 SeqNum 分配给客户。 Use PARTITION BY GroupId so that the number starts from 1 in every group.使用 PARTITION BY GroupId 以便每个组中的数字从 1 开始。 I would ORDER BY CustomerId我会按 CustomerId 订购

Step 2. Use the ROW_NUMBER() function to assign a SeqNum to the Licences.步骤 2. 使用 ROW_NUMBER() function 将 SeqNum 分配给许可证。 Use PARTITION BY GroupId so that the number starts from 1 in every group.使用 PARTITION BY GroupId 以便每个组中的数字从 1 开始。 ORDER BY LicenseId because your ask is to "assign each customer the next available LicenceId within their group". ORDER BY LicenseId 因为您的要求是“为每个客户分配其组内的下一个可用的 LicenceId”。

Now use these 2 queries to update LicenseId in Customer table.现在使用这 2 个查询来更新 Customer 表中的 LicenseId。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 INSERT到另一个表中的表和UPDATE外键(Sql Server 2008) - INSERT into table and UPDATE foreign key in another table (Sql Server 2008) 如何使用另一个表中的新列更新现有表? - How to update an existing table with a new column from another table? 从另一个表中的键更新外键 - update foreign key from key in another table SQL 服务器:如何访问由外键链接的另一个表中的列? - SQL Server : how to acces to a column from another table linked by foreign key? 通过外键列在SQL Server上进行表分区 - Table partitioning on sql server by foreign key column 使用关联表的新外键更新表的列 - Update column of a table with new foreign key of associated table 使用主键和外键从另一个表更新表中所有行的列 - Update Column Of All Rows In A Table From Another Table Using Primary Key And Foreign Key 如何将 JOIN 表中的 ID 迁移到 PostgreSQL 中的外键列 - How to migrate IDs from JOIN table into foreign key column in PostgreSQL 如何将 JOIN 表中的 ID 迁移到 MySQL 中的外键列 - How to migrate IDs from JOIN table into foreign key column in MySQL SQL Server从表中选择主键在另一个表中不显示为外键的表 - SQL Server Select from table where primary key does not appear as foreign key in another table
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM