2017-03-22 68 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只有兩列,它們是; ColumnName and Value

我有一個名爲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 

注:DefaultValues七列,它們是; AccountCode名稱地址SignatureRequiredPetRegisteredBrochureTypeMembershipType

對於值的MemberInfo是NULL,在這種情況下是PetRegisteredMembershipType我想從相應的列在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作爲表格發佈,我將展示如何做到這一點。 –

相關問題