2017-03-22 94 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作为表格发布,我将展示如何做到这一点。 –