SQL 服务器中的标量函数、table 值函数和聚合函数之间的区别?

Difference between scalar, table-valued, and aggregate functions in SQL server?

SQL 服务器中标量值函数、table 值函数和聚合函数之间的区别是什么?从查询中调用它们需要不同的方法,还是我们以相同的方式调用它们?

标量函数returns单个值。它甚至可能与您数据库中的 table 无关。

一个 tabled-valued 函数 returns 您指定的行的列 table 符合您的选择标准。

一个 aggregate-valued 函数 returns 跨行的计算 table -- 例如求和值。

标量函数

标量函数(有时称为 User-Defined 函数/UDF)return 作为 return 值的单个值,而不是结果集,并且可以在大多数情况下使用放置在查询或 SET 语句中,FROM 子句除外(可能还有其他地方?)。此外,标量函数可以通过 EXEC 调用,就像存储过程一样,尽管使用此功能的场合并不多(有关此功能的更多详细信息,请参阅我对以下问题的回答 DBA.StackExchange:Why scalar valued functions need execute permission rather than select?)。这些可以在 T-SQL 和 SQLCLR 中创建。

  • T-SQL (UDF):

    • 在 SQL Server 2019 之前:这些标量函数通常是一个性能问题,因为它们通常 运行 每行 returned(或扫描)and 始终禁止并行执行计划。
    • 从 SQL Server 2019 开始:某些 T-SQL 标量 UDF 可以 内联,即将它们的定义直接放入查询中,这样查询不调用 UDF(类似于 iTVF 的工作方式(见下文))。有一些限制可以阻止 UDF 被内联(如果以前不是这个词,现在是),并且由于多种因素,可以内联的 UDF 并不总是被内联。可以在数据库、查询和单个 UDF 级别禁用此功能。有关此非常酷的新功能的更多信息,请参阅:Scalar UDF Inlining(务必查看 "requirements" 部分)。
  • SQLCLR (UDF): 这些标量函数通常每行 运行 returned 或已扫描,但与 T-SQL UDF 相比有两个重要的好处:

    • 从 SQL Server 2012 开始,如果 UDF 不执行 any 数据,return 值可以 constant-folded 进入执行计划访问,如果它被标记为 IsDeterministic = true。在这种情况下,该函数不会每行 运行。
    • SQLCLR 标量函数 可以 在并行计划中工作 ( ) 如果它们不执行 any 数据库访问。

Table-Valued 函数

Table-Valued 函数 (TVF) return 结果集,可用于 FROM 子句、JOINCROSS APPLY / [=任何查询的 17=],但与简单视图不同,它不能是任何 DML 语句的目标 (INSERT / UPDATE / DELETE)。这些也可以在 T-SQL 和 SQLCLR 中创建。

  • T-SQL MultiStatement (TVF):这些TVF,顾名思义,可以有多个语句,类似于Stored Procedure。无论他们要 return 得到什么结果,都存储在一个 Table 变量中,并在最后 return 编辑;意思是,在函数完成处理之前,什么都不会 returned。报告给查询优化器(影响执行计划)的估计行数 return 取决于 SQL 服务器的版本:

    • 在 SQL Server 2014 之前:这些总是报告 1(是的,只有 1)行。
    • SQL Server 2014 和 2016:它们始终报告 100 行。
    • 从 SQL Server 2017 开始:默认报告 100 行,但在某些情况下,由于新的 Interleaved Execution 功能,行计数将相当准确(基于当前统计数据)。
  • T-SQL 内联 (iTVF): 这些 TVF 只能是单个语句,并且该语句是一个完整的查询,就像一个看法。事实上,内联 TVF 本质上是一个接受输入参数以用于查询的视图。它们也不缓存自己的查询计划,因为它们的定义被放入使用它们的查询中(与此处描述的其他对象不同),因此它们可以比其他类型的 TVF ( ) 优化得更好。这些 TVF 性能非常好,如果可以在单个查询中处理逻辑,则首选这些 TVF。

  • SQLCLR (TVF): 这些 TVF 类似于 T-SQL MultiStatement TVF,因为它们构建了整个结果在最后释放所有内存之前设置在内存中(即使它是交换/页面文件)。报告给查询优化器(影响执行计划)的估计行数 return 始终为 1000 行。鉴于固定的行数远非理想,请支持我的请求以允许指定行数:Allow TVFs (T-SQL and SQLCLR) to provide user-defined row estimates to query optimizer

  • SQLCLR Streaming (sTVF): 这些 TVF 允许复杂的 C# / VB.NET 代码就像常规 SQLCLR TVF,但它们的特殊之处在于它们 return 在生成它们时调用查询的每一行 ( )。此模型允许调用查询在发送第一个结果后立即开始处理结果,因此查询不需要等待函数的整个过程完成才能看到任何结果。而且它需要更少的内存,因为在过程完成之前结果不会存储在内存中。他们估计的行数ll return,报告给查询优化器(影响执行计划)的总是 1000 行。鉴于固定的行数远非理想,请支持我的请求以允许指定行数:Allow TVFs (T-SQL and SQLCLR) to provide user-defined row estimates to query optimizer

聚合函数

User-Defined 聚合 (UDA) 是类似于 SUM()COUNT()MIN()、[=24= 的聚合] 等,通常需要一个 GROUP BY 子句。这些只能在 SQLCLR 中创建,并且在 SQL Server 2005 中引入了该功能。此外,从 SQL Server 2008 开始,UDA 得到增强以允许多个输入参数 ( ) .一个特别的缺陷是不了解组内的行排序,因此在 SAFE 程序集内不可能创建 运行ning 总数,如果可以保证排序,这将相对容易。


另请参阅:

标量函数

Returns 单个值。这就像使用 T-SQL 语法在其他编程语言中编写函数一样。

Table 值函数

与上面的相比有点不同。 Returns 一个 table 值。在此函数的主体内,您编写一个查询,该查询将 return 精确 table。 例如:

CREATE FUNCTION <function name>(parameter datatype)

RETURN table

AS

RETURN

(

-- *write your query here* ---

)

请注意,此处没有 BEGIN & END 语句。

聚合函数

包括与 GROUP 子句一起使用的内置函数。例如:SUM()MAX()MIN()AVG()COUNT()是聚合函数。

聚合函数和标量函数都是return单个值,但标量函数基于单个输入运行参数而聚合函数对单个输入 值集 (集合或列名称)进行操作。标量函数的示例是字符串函数、ISNULL、ISNUMERIC,聚合函数的示例是 AVG、MAX 以及您可以在 Microsoft 网站的 Aggregate Functions 部分找到的其他函数。

Table-值函数 return a table 无论是否存在任何输入参数。此功能的执行是通过将它们用作常规物理 table 例如:SELECT * FROM fnGetMulEmployee()

以下 link 对理解差异非常有用:https://www.dotnettricks.com/learn/sqlserver/different-types-of-sql-server-functions