TSQL - 表值函数中的If..Else语句 - 无法通过

Art*_*tur 17 sql t-sql database sql-server user-defined-functions

在发布之前我已经阅读了几篇关于开发USD函数的文章,但没有遇到我的问题的解决方案......具体如下:

我有一个非常简单的数据库,存储篮球运动员,包括ID,年龄,身高和姓名列.我想要做的是使用一个参数@set varchar(10)实现一个函数'height',取决于一个@set值将触发不同的select语句

我试图实现的是psuedo代码:

CREATE FUNCTION [dbo].[age](@set varchar(10))
RETURNS TABLE
AS
BEGIN

    IF  (@set = 'tall')
         SELECT * from player where height > 180

    ELSE IF (@set = 'average')
         SELECT * from player where height >= 155 and height <=175

    ELSE IF (@set = 'low')
         SELECT * from player where height < 155
END
Run Code Online (Sandbox Code Playgroud)

任何人都可以给我一个提示如何实现它?

Ric*_*iwi 21

最简单的形式总是最好的

CREATE FUNCTION [dbo].[age](@set varchar(10))
RETURNS TABLE
AS RETURN
SELECT * from player
where ((@set = 'tall' and height > 180)
   or (@set = 'average' AND height >= 155 and height <=175)
   or (@set = 'low' AND height < 155))
GO
Run Code Online (Sandbox Code Playgroud)

这种形式被称为内嵌表函数,这意味着SQL Server的免费将它扩大到直接参与玩家在线一个更大的查询其他表,使其进行无限1更好的比一个多语句表值函数.

你可能更喜欢这样,所以你的范围是完整的(你有175和180之间的差距)

where ((@set = 'tall' and height > 180)
   or (@set = 'average' AND height >= 155 and height <= 180)
   or (@set = 'low' AND height < 155))
Run Code Online (Sandbox Code Playgroud)

解析变量@set时,SQL Server负责处理分支的短路.

1夸张,但只是轻微的


Cad*_*oux 17

你很亲密 使用多语句表值函数需要在函数中指定和填充返回表:

CREATE FUNCTION [dbo].[age](@set varchar(10))
RETURNS @Players TABLE
(
    -- Put the players table definition here
) 
AS
BEGIN

    IF  (@set = 'tall')
         INSERT INTO @Players SELECT * from player where height > 180

    ELSE IF (@set = 'average')
         INSERT INTO @Players SELECT * from player where height >= 155 and height <=175

    ELSE IF (@set = 'low')
         INSERT INTO @Players SELECT * from player where height < 155

    RETURN -- @Players (variable only required for Scalar functions)

END
Run Code Online (Sandbox Code Playgroud)

正如理查德的回答所示,我建议使用内联TVF.它可以从您的语句中推断表返回.

另请注意,多语句和内联TVF确实非常不同.内联TVF不是优化器的黑盒子,更像是参数化视图,优化器能够在同一执行计划中重新排列其他表和视图.


SQL*_*ace 11

为什么要对此进行硬编码,创建高度表,然后获取对该范围有效的所有高度

SELECT * from player p
join Heights h on p.height between h.heightStart and h.heightEnd 
WHERE h.height  = @set
Run Code Online (Sandbox Code Playgroud)


Hog*_*gan 5

这应该有效。

SELECT * FROM player 
WHERE
  height > CASE 
            WHEN @set = 'tall' THEN 180
            WHEN @set = 'average' THEN 154
            WHEN @set = 'low' THEN 0
          END
Run Code Online (Sandbox Code Playgroud)

我将把 < 案例留给您欣赏。