2012-11-29 35 views
1

在具有多個對象的一對多關係並且每個使用來自單獨表的名稱屬性的設置中。例如使用備用/缺省值爲缺失關係創建視圖

Building(BuildingName), Floor(FloorName) 

如果大樓有2名(2個languageIDs)和5層樓,其中只有3層樓有兩個語言ID名字,我想還是有10個結果條目。當缺少語言標識時,缺失地板名稱,從不匹配的樓層標識中拉出(默認)。

+0

我不知道你真正想要的,但我懷疑你可能尋找某種「OUTER JOIN」。你能發佈來自兩個表格的樣本數據和預期的查詢結果嗎?一個可以直接複製並粘貼到SSMS中的獨立腳本將是理想的。 – Pondlife

+0

'OUTER JOIN'會給你你想要的行。 'COALESCE'函數將允許你用默認值替換連接返回的任何缺失(NULL)值。提供樣本數據和期望的結果將導致更詳細的迴應。 – HABO

+0

我一直在尋找'COALESCE'功能,但我是基爾試圖找出在這方面 – Daniel

回答

1

這是沿着正確的路線爲你所追求的?

Runnable的例子在這裏: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 
+0

當英文條目丟失時是否可以默認爲法語? – Daniel

+0

是 - 檢查您希望如何確定默認語言 - 是否應該選擇可用於給定樓層的任何語言,建築物可用的任何語言,或具有優先級列表的默認語言的特定子集? – JohnLBevan

+0

只是任何作品,基本上我只是試圖避免名稱中的空值 – Daniel