我在过滤值模式中有四个表,我无法确定如何扩展现有视图查询以包含基于过滤结果的附加列。
一个表保存默认项目记录,我在下面的示例中称这些ItemKeys。此表还包含每个项目的默认值和默认描述。在示例中,这是dbo.Defaults表。
下一个表是一个表,用于为后续过滤表对这些项的集合进行分组。在示例中称为dbo.FilterGroup。
最后两个表是过滤器,它们指向FilterGroup和Defaults以及它们自己的值和描述。这些表仅包含Items的记录,当使用FilterGroup时,它们将按顺序进行筛选:Filter2> Filter1> Default。正如您将在示例中看到的,这意味着如果Filter1具有项目记录,它将覆盖默认值,并且Filter2将覆盖Filter1(如果存在)。
当前视图仅寻求恢复过滤器数据的Value
部分,并且我必须想出一种方法来恢复生成的过滤项的Value
和Description
。
让我向您展示我应该更清楚地表明情况的例子:
表和数据设置:
--dbo.Defaults
IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'
AND TABLE_NAME='Defaults') drop table dbo.Defaults;
CREATE TABLE dbo.Defaults (
ItemKey varchar(128),
DefaultValue varchar(128),
DefaultDesc varchar(512),
) ON [PRIMARY]
GO
insert into dbo.Defaults VALUES ('Fruit1','Apple','system default value')
insert into dbo.Defaults VALUES ('Fruit2','Orange','system default value')
insert into dbo.Defaults VALUES ('Fruit3','Pear',NULL)
insert into dbo.Defaults VALUES ('Fruit4','Tomato','system default value')
--dbo.Filter group
IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'
AND TABLE_NAME='FilterGroup') drop table dbo.FilterGroup;
CREATE TABLE dbo.FilterGroup (
ID integer NOT NULL
IDENTITY (1,1) CONSTRAINT [PK_ParamFilterSet] PRIMARY KEY CLUSTERED ([ID] ASC) WITH (IGNORE_DUP_KEY = OFF),
GroupName varchar(128)
) ON [PRIMARY]
GO
insert into FilterGroup values ('Group1')
--dbo.Filter1
IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'
AND TABLE_NAME='Filter1') drop table dbo.Filter1;
CREATE TABLE dbo.Filter1 (
ItemKey varchar(128), --Defaults.ItemKey
GroupID int, --FilterGroup.ID
FilterValue varchar(128),
FilterDesc varchar(512),
) ON [PRIMARY]
GO
insert into dbo.Filter1 VALUES ('Fruit2',1,'Seedless Orange',NULL)
--dbo.Filter2
IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'
AND TABLE_NAME='Filter2') drop table dbo.Filter2;
CREATE TABLE dbo.Filter2 (
ItemKey varchar(128), --Defaults.ItemKey
GroupID int, --FilterGroup.ID
FilterValue varchar(128),
FilterDesc varchar(512),
) ON [PRIMARY]
GO
insert into dbo.Filter1 VALUES ('Fruit3',1,'Pyrus Pear','filter2 value')
我的查询:
SELECT fg.GroupName as [FilterGroup]
,d.ItemKey as [ItemKey]
,coalesce(f2.FilterValue, f1.FilterValue ,d.DefaultValue) as [Value]
FROM dbo.Defaults d cross join dbo.FilterGroup fg
left outer join dbo.Filter1 f1 on f1.ItemKey = d.ItemKey
and f1.GroupID = fg.ID
left outer join dbo.Filter2 f2 on f2.ItemKey = d.ItemKey
and f1.GroupID = fg.ID
如上所述,现有查询正确过滤,将Filter2值恢复为Filter1值,Filter1值超过默认值,如果给定项目上没有过滤器,则返回默认值。
我正在努力弄清楚的是我如何根据select coalesce set中的哪个过滤器来包含f1.FilterDesc,f2.FilterDesc或d.DefaultDesc。如何执行此连接并从coalesce中出现的表中提取“value”和“desc”列?
我非常友好地感谢您提供任何帮助!
一个简单的方法是:
SELECT fg.GroupName as [FilterGroup],
d.ItemKey as [ItemKey],
coalesce(f2.FilterValue, f1.FilterValue, d.DefaultValue) as [Value],
(case when f2.FilterValue is not null then 'f2'
when f1.FilterValue is not null then 'f1'
else 'default'
end) as which
FROM dbo.Defaults d cross join
dbo.FilterGroup fg left outer join
dbo.Filter1 f1
on f1.ItemKey = d.ItemKey and f1.GroupID = fg.ID left outer join
dbo.Filter2 f2
on f2.ItemKey = d.ItemKey and f1.GroupID = fg.ID;
一种更聪明的方式将逻辑放入from
:
SELECT fg.GroupName as [FilterGroup],
d.ItemKey as [ItemKey],
coalesce(f2.FilterValue, f1.FilterValue, d.DefaultValue) as [Value],
coalesce(f2.which, f1.which, 'default') as which
FROM dbo.Defaults d cross join
dbo.FilterGroup fg left outer join
(SELECT f1.*, 'f1' as which
FROM dbo.Filter1 f1
) f1
on f1.ItemKey = d.ItemKey and f1.GroupID = fg.ID left outer join
(SELECT f2.*, 'f2' as which
FROM dbo.Filter2 f2
) f2
on f2.ItemKey = d.ItemKey and f1.GroupID = fg.ID;
最后一个条件应该是f1.GroupId = fg.ID
还是f2.GroupID = fg.ID
?
除了戈登的答案排名方法:
;with allFilters as (
select f.ItemKey,
f.GroupID,
f.FilterValue,
f.FilterDesc ,
2 rank --<<<
from dbo.Filter1 f
union all
select f.ItemKey,
f.GroupID,
f.FilterValue,
f.FilterDesc ,
1 rank --<<<
from dbo.Filter2 f
union all
select f.ItemKey,
NULL GroupID,
f.DefaultValue,
f.DefaultDesc ,
3 rank --<<<
from dbo.Defaults f
),
filtersRanked as
(
select f.ItemKey,
f.GroupID,
f.FilterValue,
f.FilterDesc ,
-- now computing most preferred per ItemKey
ROW_NUMBER() OVER(PARTITION BY f.ItemKey ORDER BY f.rank ASC) rn
from allFilters f
)
SELECT fg.GroupName as [FilterGroup],
f.ItemKey as [ItemKey],
f.FilterValue,
f.FilterDesc
FROM dbo.FilterGroup fg
left join filtersRanked f
on (f.GroupID = fg.ID or f.GroupID is NULL) -- NULL support for defaults
and f.rn = 1 --<<< "top 1" by rank
易于操纵哪个源具有更高的优先级。
输出:
FilterGroup ItemKey FilterValue FilterDesc
Group1 Fruit1 Apple system default value
Group1 Fruit2 Seedless Orange (null)
Group1 Fruit3 Pyrus Pear filter2 value
Group1 Fruit4 Tomato system default value
http://sqlfiddle.com/#!18/1511d/1
你也有一些错别字:
Filter2
f1.GroupID
的连接谓词中提到Filter2
而不是f2.GroupID