在下面,第一行是标题,所有值都是|分隔。
我有一个名为 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 和 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 ,名称,地址, SignatureRequired , PetRegistered , BrochureType < / em>和 MembershipType 。
对于 MemberInfo 中的值为NULL,在本例中为 PetRegistered 和 MembershipType ,我希望来自相应列的值 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 :(得分: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