1

次の SQL を検討してください。

declare @t1 table(site int, id int, name varchar(2))
declare @t2 table(site int, id int, mark int)

insert into @t1
select 1,1,'A'
union select 1,2,'B'
union select 1,3,'C'
union select 2,2,'D'
union select 2,3,'C'

insert into @t2
select 1,1,10
union select 1,2,20
union select 0,3,30
union select 1,3,40
union select 2,3,40
union select 2,3,40

select distinct a.site, a.id,a.name,b.mark
from @t1 a 
inner join @t2 b
on (a.site =b.site or b.site = 0) and a.id = b.id
where a.site=1

次の結果が生成されます

サイトIDネームマーク
----------------------------
1 1 A 10
1 2 B 20
1 3 C 30
1 3 C 40

あたりです。

しかし、私は人のデータが一度だけ欲しいです。SQL はまず、特定のサイトの @t2 に人物のエントリがあるかどうかを確認する必要があります。エントリが見つかった場合は、それを使用します。そうでない場合、その人物のマークは、サイト 0 の同名の人物のマークになります。

この場合、次のような結果が必要です。

サイトIDネームマーク
----------------------------
1 1 A 10
1 2 B 20
1 3 C 40

しかし、(1,3,40) が @t2 にない場合、結果は次のようになります。

サイトIDネームマーク
----------------------------
1 1 A 10
1 2 B 20
1 3 C 30

これどうやってするの?Common Table Expression を使用して実行できます。だから私にもっと速い方法を教えてください。約1億行で実行します。

4

2 に答える 2

0

t2テーブルに2回外部結合し、サブクエリを使用して、一致するレコードまたはゼロであるレコードのみが含まれるようにします。

  Select distinct a.site, a.id, a.name, 
       coalesce(sm.mark, zs.mark) mark
  from @t1 a 
      Left Join @t2 sm -- for site match
          on sm.id = a.id
              And sm.site = a.site
      Left Join @t2 zs -- for zero site
          on zs.id = a.id
              And zs.site = 0
  Where Exists (Select * From @t2
                Where id = a.id 
                  And Site In (a.Site, 0))
     And a.site=1
于 2012-12-13T16:22:26.317 に答える
0

すべての条件をon句にまとめることができます。

declare @target_site as Int = 1
select distinct a.site, a.id, a.name, b.mark
  from @t1 as a inner join
    @t2 as b on a.site = @target_site and a.id = b.id and
      ( a.site = b.site or ( b.site = 0 and not exists ( select 42 from @t2 where site = @target_site and id = a.id ) ) )
于 2012-12-13T16:49:38.973 に答える