2017-03-22 9 views
0

다음에서 첫 번째 행은 표제이며 모든 값은 | 구분됩니다. 다음과 같이열 이름을 기준으로 다른 테이블의 기본값 가져 오기

나는 MemberInfo가라는 테이블이 있습니다

ColumnName|Value 
AccountCode|FredsDiscounts 
Id|1 
Name|Joe Bloggs 
Address|1 Puddle lane, PL99 9PL 
SignatureRequired|0 
PetRegistered|NULL 
BrochureType|Post 
MembershipType|NULL 

참고 : MemberInfo가은 단지 두 개의 열을 가지고; 열 이름 다음과 같이

나는 DefaultValues ​​라는 다른 테이블이 :

AccountCode|Name|Address|SignatureRequired|PetRegistered|BrochureType|MembershipType 
FredsDiscounts|Unknown|Unknown|1|0|Email|Normal 
JillsSupers|Unknown|Unknown|1|0|Post|Super 
GreggsFurniture|Unknown|Unknown|1|0|Email|None 
JeremySwift|Unknown|Unknown|1|0|Telephone|Normal 

참고 :은 7 개 열을 가지고 DefaultValues; AccountCode, 이름, 주소, SignatureRequired, PetRegistered, BrochureTypeMembershipType. 값에 대한

이 경우 PetRegisteredMembershipType 있습니다 NULL입니다 MemberInfo가, 에서 나는 DefaultValues ​​의 해당 열에서 값이 자신의 자리를 먹고 싶어.

AccountCode을 기반으로 사용할 행을 선택해야합니다. 내가 사전에 그 이름을 모르는 상태에서 열을 참조하는 방법을 모른다

AccountCode|FredsDiscounts 
ColumnName|Value 
Id|1 
Name|Joe Bloggs 
Address|1 Puddle lane, PL99 9PL 
SignatureRequired|0 
PetRegistered|0 
BrochureType|Post 
MembershipType|Normal 

다음과 같이

원하는 결과가 될 것입니다. 다음과 같이

내가 현재 사용하는 방법은 다음과 같습니다

DECLARE 
    @AccountCode VARCHAR(MAX) = 'FredsDiscounts' 

SELECT 
    MemberInfo.ColumnName, 
    CASE WHEN MemberInfo.Value IS NOT NULL THEN MemberInfo.Value ELSE Defaults.[DefaultValue] END AS Value 
FROM 
    MemberInfo 
    LEFT OUTER JOIN (
     (SELECT 'AccountCode' AS [ColumnName], @AccountCode AS [DefaultValue]) UNION 
     (SELECT TOP 1 'Name' AS [ColumnName], DefaultValues.[Name] AS [DefaultValue] FROM DefaultValues WHERE DefaultValues.Accountcode = @AccountCode) UNION 
     (SELECT TOP 1 'Address' AS [ColumnName], DefaultValues.[Address] AS [DefaultValue] FROM DefaultValues WHERE DefaultValues.Accountcode = @AccountCode) UNION 
     (SELECT TOP 1 'SignatureRequired' AS [ColumnName], DefaultValues.[SignatureRequired] AS [DefaultValue] FROM DefaultValues WHERE DefaultValues.Accountcode = @AccountCode) UNION 
     (SELECT TOP 1 'PetRegistered' AS [ColumnName], DefaultValues.[PetRegistered] AS [DefaultValue] FROM DefaultValues WHERE DefaultValues.Accountcode = @AccountCode) UNION 
     (SELECT TOP 1 'BrochureType' AS [ColumnName], DefaultValues.[BrochureType] AS [DefaultValue] FROM DefaultValues WHERE DefaultValues.Accountcode = @AccountCode) UNION 
     (SELECT TOP 1 'MembershipType' AS [ColumnName], DefaultValues.[MembershipType] AS [DefaultValue] FROM DefaultValues WHERE DefaultValues.Accountcode = @AccountCode) 
    ) AS Defaults ON [Defaults].[ColumnName] = MemberInfo.[ColumnName] 

... 아주 우아하지.

이 작업을 수행하는 적절한 방법은 무엇입니까?

+0

두 테이블 모두에 대해 왼쪽 조인을 사용하고 ISNULL 또는 COALESCE를 사용합니다. –

답변

0

이 모든 내용을 입력하지는 않겠지 만 기본 개념을 보여줍니다. 여기에 왼쪽 조인을 사용하기 만하면됩니다.

select mi.AccountCode 
    , PetRegistered = ISNULL(mi.PetRegistered, d.PetRegistered) 
from MemberInfo mi 
left join DefaultValues d on d.AccountCode = mi.AccountCode 

--- 편집 ---

여기 진짜 문제는 당신이 좀 더 정규화 된 테이블에서와보다 더 많은 코드를 작성해야 할 것 EAV로 작업되어 있기 때문에 구조. 다음은 당신을 위해 일해야합니다.

declare @AccountCode VARCHAR(MAX) = 'FredsDiscounts'; 

with MemInfo as 
(
    select AccountCode = max(case when ColumnName = 'AccountCode' then Value end) 
     , Id = max(case when ColumnName = 'Id' then Value end) 
     , Name = max(case when ColumnName = 'Name' then Value end) 
     , Address = max(case when ColumnName = 'Address' then Value end) 
     , SignatureRequired = max(case when ColumnName = 'SignatureRequired' then Value end) 
     , PetRegistered = max(case when ColumnName = 'PetRegistered' then Value end) 
     , BrochureType = max(case when ColumnName = 'BrochureType' then Value end) 
     , MembershipType = max(case when ColumnName = 'MembershipType' then Value end) 
    from MemberInfo mi 
    where AccountCode = @AccountCode 
) 

select mi.AccountCode 
    , mi.Id 
    , Name = isnull(mi.Name, dv.Name) 
    , Address = isnull(mi.Address, dv.Address) 
    , SignatureRequired = isnull(mi.SignatureRequired, dv.SignatureRequired) 
    , PetRegistered = isnull(mi.PetRegistered, dv.PetRegistered) 
    , BrochureType = isnull(mi.BrochureType, dv.BrochureType) 
    , MembershipType = isnull(mi.MembershipType, dv.MembershipType) 
from MemInfo mi 
inner join DefaultValues dv on dv.AccountCode = mi.AccountCode 
+0

게시물에 테이블 작성과 같은 형식으로 세부 사항이있는 경우 해독이 훨씬 쉬울 것입니다.EAV (엔티티 속성 값)라고하는 안티 패턴으로 작업하고 있습니다. 개념은 동일하지만 EAV를 사용 가능한 테이블로 전환하기 위해 먼저 동적 피벗을 수행해야하기 때문에 쿼리가 무한히 복잡해 지므로 DefaultValues ​​테이블에 대한 왼쪽 조인을 수행 할 수 있습니다. –

+0

고맙습니다. 이 솔루션을 포함하는 내 질문을 편집했습니다. 원하지 않는 것에 대한 예입니다. –

+0

당신이 가지고있는 상위 1 개의 다중 쿼리 솔루션은 꽤보기 흉합니다. 그 MemberInfo를 테이블로 게시하면 어떻게 할 수 있는지 보여줄 것입니다. –