2013-05-13 36 views
2

我有三個表如下:更新列基於3級表和2分的規則

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考慮以下規則:

  1. 應該從@ TableB.name得到的值,前提是同@ TableA.name不應該存在於@TableA相同的ID。所以對於ID = 1,@ TableC.name應該是任何值,但A4,SH,9K。

  2. @ tableC.Name應爲每個@ TableC.ID的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 

SQL Server 2012: JOIN 3 tables for a condition

回答

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 

有可能是一個更優雅的做法,但這是一個快速的方法,如果它不是很多o在@tableC中的f行。

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 

但願,熱膨脹係數的名字給人一種我是如何思考問題的線索。

如果隨機性是一個要求,那麼它應該引入接近第一個ROW_NUMBER()表達式(在ORDER BY子句中)。