2017-03-22 34 views
0

以下では、最初の行は見出しであり、すべての値は|区切られた次のように列名に基づいて別の表のデフォルト値を取得

Iは、の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である2つだけの列を有します。 列名および。次のように

私は、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名前住所SignatureRequiredPetRegisteredBrochureTypeMembershipTypePetRegisteredMembershipTypeあり、この場合、私はDefaultValuesの対応する列の値がその場所を取るしたいNULLですのMemberInfoの値については、

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 

--- EDIT ---

ここでの本当の問題は、あなたがより多くの正規化されたテーブルの場合と比べて、あなたがより多くのコードを記述する必要があるとしている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をテーブルとして投稿すると、あなたがそれを行う方法を示します。 –

関連する問題