2012-11-29 7 views
1

개체의 여러 일대 다 관계가 있고 각각이 별도의 테이블에서 오는 이름 특성을 사용하는 설치에서. 누락 된 관계에 대한 대체/기본값이있는보기 만들기

Building(BuildingName), Floor(FloorName) 

건물이 2 명 (2 languageIDs) 만 3 층이 모두 언어 ID의 이름이 5 층에있는 경우 예를

를 들어, 나는 10 개 결과 항목이 여전히 싶다. 언어 이름이 누락되었을 때 누락 된 바닥 이름은 일치하지 않는 층 ID에서 가져옵니다 (기본값).

+0

어떤 종류의 'OUTER JOIN'을 찾고 있습니다. 두 테이블 및 예상 쿼리 결과의 샘플 데이터를 게시 할 수 있습니까? 직접 복사하여 SSMS에 직접 붙여 넣을 수있는 자체 포함 된 스크립트가 이상적입니다. – Pondlife

+0

'OUTER JOIN'은 원하는 행을 줄 것입니다. 'COALESCE' 함수는 join에 의해 리턴 된 누락 된 (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

그냥 어떤 작품, 기본적으로 이름에 null 값을 피하려고 노력하고있어 – Daniel

관련 문제