关于MS SQL2012中函数的一般性问题。我已经使用SQL 15年了,并且已经将大部分内容用于相当高级的水平,但从未使用过函数。
我只是想知道一个功能是否可以用于以下......
我的查询有一个大的case语句,查询也按case语句的结果分组 - 这意味着我对case语句所做的每一个更改都必须在Group By子句中复制,这个维护是非常耗时的(特别是因为我总是忘记更新group by子句中的case语句)。
这是我查询的理论示例....
Select
Field1,
Field2,
Field3,
Field4,
Case
when Field2 like ('%abc%') then 'Category1'
when Field2 like ('%def%') then 'Category2'
/*plus around 20 more 'when' lines*/
else 'CategoryX' end as 'Category'
From table
Group by
Case
when Field2 like ('%abc%') then 'Category1'
when Field2 like ('%def%') then 'Category2'
/*plus around 20 more 'when' lines*/
else 'CategoryX' end
我知道我可以对它进行子查询,然后通过subQuery.Category进行分组,但是,由于我之前从未使用过函数,我只是想知道我是否可以创建Category
接受Field2
的函数,运行case语句并将结果与表中的其余数据一起输出?
答案 0 :(得分:3)
比用户定义的函数(在我看来)更好的是计算列:
alter table
add category as (Case when Field2 like ('%abc%') then 'Category1'
when Field2 like ('%def%') then 'Category2'
/*plus around 20 more 'when' lines*/
else 'CategoryX'
end);
为什么我比功能更喜欢这个?
field2
列绑定。category
上创建索引。category
列,并且会正确填充。修改列需要删除并重新添加。
一个缺点是用户需要正确的权限才能添加列。删除并重新添加列可能会对使用SCHEMABINDING的代码产生影响。 (为什么SQL Server不允许修改计算列?)
请注意,此解决方案和函数都有一个缺点:逻辑在查询中不明显,因此在不同时间运行的相同查询可能会产生不同的结果。
答案 1 :(得分:2)
您可以创建内联表函数来隐藏复杂的逻辑:
create function dbo.udfGetR
(
--param here
)
returns table
as return
Select
Field1,
Field2,
Field3,
Field4,
Case
when Field2 like ('%abc%') then 'Category1'
when Field2 like ('%def%') then 'Category2'
/*plus around 20 more 'when' lines*/
else 'CategoryX' end as 'Category'
From table
Group by
Case
when Field2 like ('%abc%') then 'Category1'
when Field2 like ('%def%') then 'Category2'
/*plus around 20 more 'when' lines*/
else 'CategoryX' end
称之为
select * from dbo.udfGetR(--param)
答案 2 :(得分:1)
另外两个明显的解决方案:
使用CTE:
WITH cte As
(
SELECT
...
CASE
WHEN Field2 like '%abc%' THEN 'Category1'
...
ELSE 'CategoryX'
END As 'Category'
FROM
table
)
SELECT
...
FROM
cte
GROUP BY
Category
;
使用CROSS APPLY
:
SELECT
...
C.Category
FROM
table As T
CROSS APPLY
(
SELECT
CASE
WHEN T.Field2 Like '%abc%' THEN 'Category1'
...
ELSE 'CategoryX'
END
) As C (Category)
GROUP BY
C.Category
;