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 中的相同ID 不应该存在相同的@TableA.name。所以对于 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:为一个条件加入 3 个表

4

2 回答 2

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 中的行不多,这是一种快速的方式。

于 2013-05-13T09:13:35.113 回答
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子句中)的地方引入它。

于 2013-05-13T09:36:20.063 回答