我有三张表如下:
declare @tableA table (id int, name varchar(2));
declare @tableB table (name varchar(2));
declare @tableC table (id int, name varchar(2))
insert into @tableA(id, name)
select 01, 'A4' union all
select 01, 'SH' union all
select 01, '9K' union all
select 02, 'M1' union all
select 02, 'L4' union all
select 03, '2G' union all
select 03, '99';
insert into @tableB(name)
select '5G' union all
select 'U8' union all
select '02' union all
select '45' union all
select '23' union all
select 'J7' union all
select '99' union all
select '9F' union all
select 'A4' union all
select 'H2';
insert into @tableC(id)
select 01 union all
select 01 union all
select 01 union all
select 02 union all
select 02 union all
select 03 union all
select 03;
基本上,@ TableC.ID是从@ TableA.ID(相同的行)填充的
现在,我必须考虑以下规则来填充@ tableC.Name:
它应该从@ TableB.name获取值,前提是@TableA中相同的ID不应存在相同的@ TableA.name。因此,对于ID = 1,@ TableC.name应该是任何值,但A4,SH,9K。
@ tableC.Name应为DISTINCT。所以@ TableC.Name对于相同的ID不应该有两个相同的值,但对于不同的ID,它可以具有相同的@ TableC.name。
我用来解决规则#1的查询是:(请编辑它以应用规则#2)
update c
set Name = (select top 1 b.name
from @TableB b
where b.name not in (select name from @TableA a where a.id = c.id)
order by NEWID()
)
from @tableC c
select *
from @tableC
答案 0 :(得分:0)
在执行上述代码之前清理@tableC:
declare @tableD table (id int, name varchar(2))
insert into @tableD
select distinct * from @tableC
delete from @tableC
insert into @tableC
select * from @tableD
update c
set Name = (select top 1 b.name
from @TableB b
where b.name not in (select name from @TableA a where a.id = c.id)
order by NEWID()
)
from @tableC c
select *
from @tableC
这可能有一种更优雅的方式,但如果@tableC中没有很多行,这是一种快捷方式。
答案 1 :(得分:0)
我不确定随机性是否是必需的。我去了一个非随机解决方案:
; with IDs as (
select distinct id from @tableA
), AllPossible as (
select i.id,b.name from IDs i cross join @tableB b
), RemoveExisting as (
select ap.id,ap.name,ROW_NUMBER() OVER (PARTITION BY ap.id ORDER BY ap.name) rn
from AllPossible ap left join @tableA a on ap.id = a.id and ap.name= a.name
where a.id is null
), COrdered as (
select id,name,ROW_NUMBER() OVER (PARTITION BY id ORDER BY id) rn
from @tableC
)
update c
set name = re.name
from
Cordered c
inner join
RemoveExisting re
on
c.id = re.id and
c.rn = re.rn
希望CTE的名称能给出我对这个问题的看法的线索。
如果要求随机性,则应在接近第一个ROW_NUMBER()
表达式的位置引入(在ORDER BY
子句中)。