メモ:Aテーブルに1行も無い時だけBテーブルから取得するクエリ

メモ

通常ケースのテーブルがあって、特定の時は上書きしたデータが欲しいってケースのクエリ。

通常、特定ともにmax1行の時は、単に両方 left join でつないで、coalesce(isnull) でOK。

SQL Server の例だと

-- max1件のケース
create table [通常] (
  [種別] int not null primary key,
  [数量] int,   
)
create table [上書き] (
  [種別] int not null primary key,
  [数量] int,
)

create table [データ] (
  [Id] bigint not null primary key,
  [種別] int not null,
)

insert into [通常] values 
(1, 10),
(2, 100),
(3, 1000)
insert into [上書き] values 
(1, 5)
insert into [データ] values 
(1, 1),
(2, 2),
(3, 3)

select
  [データ].[Id]
  , [データ].[種別]
  , coalesce([上書き].[数量], [通常].[数量]) as [数量]
from
  [データ] left join [上書き]
    on [データ].[種別] = [上書き].[種別]
  left join [通常] 
    on [データ].[種別] = [通常].[種別]

drop table [データ]
drop table [上書き]
drop table [通常]

f:id:odashinsuke:20200622183316p:plain

複数行ある場合は、上書きのを left join で繋いだあとに、通常を left join で繋ぐ条件に、上書きのデータが無いという条件を足せばOK。

-- 複数件あり得る
create table [通常] (
  [種別] int not null,
  [サブ種別] int not null,
  [数量] int, 
  primary key ([種別], [サブ種別])
)
create table [上書き] (
  [種別] int not null,
  [サブ種別] int not null,
  [取引先Id] bigint not null,
  [数量] int,
  primary key ([種別], [サブ種別], [取引先Id])
)

create table [データ] (
  [Id] bigint not null primary key,
  [種別] int not null,
  [取引先Id] bigint
)

insert into [通常] values 
(1, 1, 1),
(1, 2, 5),
(1, 3, 10),
(2, 1, 50),
(2, 2, 100),
(3, 1, 1000),
(3, 2, 10000)
insert into [上書き] values
(1, 1, 1, 30),
(1, 2, 1, 50),
(3, 1, 2, 20)
insert into [データ] values 
(1, 1, null),
(2, 1, 1),
(3, 1, 2),
(4, 2, null),
(5, 2, 1),
(6, 2, 2),
(7, 3, null),
(8, 3, 1),
(9, 3, 2)

select
  [データ].[Id]
  , [データ].[種別]
  , coalesce([上書き].[サブ種別], [通常].[サブ種別]) as [サブ種別]
  , coalesce([上書き].[数量], [通常].[数量]) as [数量]
from
  [データ] left join [上書き]
    on [データ].[種別] = [上書き].[種別]
    and [データ].[取引先Id] = [上書き].[取引先Id]
  left join [通常] 
    on [上書き].[種別] is null
    and [データ].[種別] = [通常].[種別]


drop table [データ]
drop table [上書き]
drop table [通常]

f:id:odashinsuke:20200622183521p:plain