1

オブジェクトの 1 対多のリレーションシップがいくつかあり、それぞれが別のテーブルからの名前属性を使用する設定。例えば

Building(BuildingName), Floor(FloorName)

建物に 2 つの名前 (2 つの languageID) と 5 つのフロアがあり、両方の言語 ID の名前を持つのは 3 つのフロアだけである場合、結果として 10 のエントリが必要です。言語 ID が欠落している場合に欠落しているフロア名は、一致しないフロア ID からプル (デフォルト) されます。

4

1 に答える 1

1

これはあなたが求めているものに合っていますか?

ここで実行可能な例: http://sqlfiddle.com/#!3/894e9/4

if object_id('[FloorName]') is not null drop table [FloorName]
if object_id('[BuildingName]') is not null drop table [BuildingName]
if object_id('[Floor]') is not null drop table [Floor]
if object_id('[Building]') is not null drop table [Building]
if object_id('[Language]') is not null drop table [Language]

create table [Language]
(
    Id bigint not null identity(1,1) primary key clustered
    , code nvarchar(5)
)
create table [Building]
(
    Id bigint not null identity(1,1) primary key clustered
    , something nvarchar(64)
)
create table [Floor]
(
    Id bigint not null identity(1,1) primary key clustered
    , BuildingId bigint foreign key references [Building](Id)
    , something nvarchar(64)
)
create table [BuildingName]
(
    Id bigint not null identity(1,1) primary key clustered
    , BuildingId bigint foreign key references [Building](Id)
    , LanguageId bigint foreign key references [Language](Id)
    , name nvarchar(64)
)
create table [FloorName]
(
    Id bigint not null identity(1,1) primary key clustered
    , FloorId bigint foreign key references [Floor](Id)
    , LanguageId bigint foreign key references [Language](Id)
    , name nvarchar(64)
)

insert [Language]
      select 'en-us'
union select 'en-gb'
union select 'fr'

insert [Building]
      select 'B1'
union select 'B2'

insert [Floor]
      select 1, 'F1.1'
union select 1, 'F1.2'
union select 1, 'F1.3'
union select 1, 'F1.4'
union select 1, 'F1.5'
union select 2, 'F2.1'
union select 2, 'F2.2'
union select 2, 'F2.3'
union select 2, 'F2.4'
union select 2, 'F2.5'

insert BuildingName
select b.Id
, l.id
, 'BuildingName :: ' + b.something + ' ' + l.code
from [Building] b
cross join [Language] l
where l.code in ('en-us', 'fr')

insert FloorName
select f.Id
, l.Id
, 'FloorName :: ' + f.something + ' ' + l.code
from [Floor] f
cross join [Language] l
where f.something in ( 'F1.1', 'F1.2', 'F2.1')
and l.code in ('en-us', 'fr')

insert FloorName
select  f.Id
, l.Id
, 'FloorName :: ' + f.something + ' ' + l.code
from [Floor] f
cross join [Language] l
where f.something not in ( 'F1.1', 'F1.2', 'F2.1')
and l.code in ('en-us')


declare @defaultLanguageId bigint
select @defaultLanguageId = id from [Language] where code = 'en-us' --default language is US English

select b.Id
, b.something
, bn.name
, isnull(bfn.name, bfnDefault.name)
, bl.code BuildingLanguage
from [Building] b
inner join [BuildingName] bn
    on bn.BuildingId = b.Id
inner join [Language] bl
    on bl.Id = bn.LanguageId
inner join [Floor] bf
    on bf.BuildingId = b.Id
left outer join [FloorName] bfn
    on bfn.FloorId = bf.Id
    and bfn.LanguageId = bl.Id
left outer join [Language] bfl
    on bfl.Id = bfn.LanguageId
left outer join [FloorName] bfnDefault
    on bfnDefault.FloorId = bf.Id
    and bfnDefault.LanguageId = @defaultLanguageId

編集

このバージョンでは、デフォルトで任意の言語が設定されます:

select b.Id
, b.something
, bn.name
, isnull(bfn.name, (select top 1 name from [FloorName] x where x.FloorId=bf.Id))
, bl.code BuildingLanguage
from [Building] b
inner join [BuildingName] bn
    on bn.BuildingId = b.Id
inner join [Language] bl
    on bl.Id = bn.LanguageId
inner join [Floor] bf
    on bf.BuildingId = b.Id
left outer join [FloorName] bfn
    on bfn.FloorId = bf.Id
    and bfn.LanguageId = bl.Id
left outer join [Language] bfl
    on bfl.Id = bfn.LanguageId
于 2012-11-29T18:53:22.097 に答える