这是我的疑问:
SELECT main.SomeValues, mainData.Name
FROM dbo.MainTable main JOIN
dbo.MainDataTable mainData ON
(main.dataId = mainData.dataId) AND
(mainData.Type = 1 OR mainData.Type = 2 OR mainData.Type = 3)
我在许多视图中使用类似的查询。但最后一个条件始终如一:main.Type = 1 OR main.Type = 2 OR main.Type = 3
。
我想知道如何将其解压缩到一些SQL函数。我之前从未做过任何功能。
所以它看起来像这样:
SELECT main.SomeValues, mainData.Name
FROM dbo.MainTable main
JOIN dbo.MainDataTable mainData ON main.dataId = mainData.dataId
AND (GetConditionForType()) -- more or less ;)
答案 0 :(得分:1)
您可以创建如下视图:
create view dbo.FilteredMainDataTable
as
select ...
from dbo.MainDataTable
where [Type] in (1,2,3);
然后在所有查询中使用此视图而不是dbo.MainDataTable。编译器做什么然后它在每个使用此视图的查询中“打开”视图作为其定义,这就是您想要的。函数不会这样做,它们不被视为“宏替换”
如果你坚持使用功能,你可以创建它,但它不会有你想要的“外观”。它可以是内联表值函数,如下所示:
create function dbo.fn_FilteredMainDataTable(@n1 int, @n2 int, @n3 int)
returns TABLE
return select Id, ...
from FilteredMainDataTable
where type in (@n1, @n2, @n3);
然后您加入此函数而不是MainDataTable,如下所示:
SELECT main.SomeValues, mainData.Name
FROM dbo.MainTable main
JOIN dbo.fn_FilteredMainDataTable(1,2,3) mainData ON main.dataId = mainData.dataId
^^^^^^^^^^^^^^^^^^^^^^^
以下代码显示了内联表如何在搜索谓词中使用视图推送:
if object_id('dbo.num') is not null drop table dbo.num;
go
select top 1000000
isnull(row_number() over(order by 1 / 0), 0) as n,
isnull(row_number() over(order by 1 / 0), 0) as n1
into dbo.num
from sys.columns c1 cross join sys.columns c2 cross join sys.columns c3;
go
alter table dbo.num add constraint PK_num_n primary key (n);
go
create index ix_n1_n on dbo.num (n1, n);
go
if object_id('dbo.fn_num_between') is not null drop function dbo.fn_num_between;
go
create function dbo.fn_num_between(@n1 int, @n2 int)
returns table
as
return
select n, n1
from dbo.num
where n between @n1 and @n2;
go
select *
from dbo.fn_num_between(1, 1000)
where n1 = 5;
答案 1 :(得分:0)
您可以使用内联表值函数执行此操作。 您可以将函数定义为:
create function fnFilteredTypes ()
returns table as return
(
select 1 as type
union
select 2 as type
union
select 3 as type
);
然后你可以像这样加入这个函数:
SELECT main.SomeValues, mainData.Name
FROM dbo.MainTable AS main
JOIN dbo.MainDataTable AS mainData
ON main.dataId = mainData.dataId
JOIN fnFilteredTypes() As typeFilter
ON(mainData.Type=typeFilter.type)
我不确定这个查询是否真的是你想要的,但基本上你可以理解你可以使用这个函数,就像它是一个参数化视图&直接加入它的字段。只是不要忘记它是一个功能&你用圆括号来称呼它。