2

次のように3つのテーブルがあります。

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. @TableA の同じ ID に対して同じ @TableA.name が存在してはならないという条件で、 @TableB.name から値を取得する必要があります。したがって、ID = 1 の場合、@TableC.name は A4、SH、9K 以外の値にする必要があります。

  2. @tableC.Name は、@TableC.ID ごとに DISTINCT である必要があります。したがって、@TableC.Name は同じ ID に対して 2 つの同じ値を持つべきではありませんが、異なる 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

ランダム性が要件であるかどうかはわかりません。私は無作為化されていない解決策に行きました:

; 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 に答える