【问题标题】:Possible to create a function that returns more than one column?可以创建一个返回多列的函数吗?
【发布时间】:2021-12-17 10:25:48
【问题描述】:

SQL 是否具有在表函数之外返回多列的函数的概念?下面是一个例子:

SELECT
    id,
    SPLIT_NAME(name, ' ')
FROM
    table

我希望SPLIT_NAME 函数生成两列,一列用于第一列,另一列用于最后,因此输出为:

id      first        last
1        tom         jones

我知道可以这样做:

SELECT id, SPLIT(...) first, SPLIT(...) last FROM table

或者可能带有一个表函数,例如:

SELECT id, first, last FROM table, SPLIT_NAME(name, ' ')

但是,想知道 SQL 是否有任何可以产生多个输出的标量函数,因为我认为 join 可能会非常昂贵(我认为?)如果加入像十亿行这样的东西(希望如此)函数本身可以被内联。

注意:Postgres 或 SQL Server 都可以。

【问题讨论】:

  • 哪种方言? SQL 服务器? MySQL? PostgreSQL?甲骨文?等等? (您可能需要表值函数,即使您只返回一行,这也允许多列。然后使用 APPLY 或 LATERAL 连接逐行调用该函数。但确切的答案取决于您使用的 DBMS。 )
  • @MatBailie any 很好——更多的是一个概念性问题。
  • 对于 SQL Server,您将交叉应用返回单行多列的内联表值函数。顾名思义,这是内联的。
  • 这就像说你不介意它是 C 还是 Delphi。 DBMS 之间的语法、功能等不同,它们实际上是具有不同模式的不同语言。这是一个非常特定于 DBMS 的问题。
  • @MatBailie 刚刚更新了它。 SQL Server 或 Postgres 都可以。

标签: sql sql-server postgresql user-defined-functions table-functions


【解决方案1】:

你需要的两个概念是……

  • 内联表值函数(即使只返回一行,也允许多列)
  • APPLY 或 LATERAL JOIN 为每个输入行调用函数

例如,SQL Server 可以写成...

SELECT
  table.id,
  name_parts.first_name,
  name_parts.last_name
FROM
  table
CROSS APPLY
  SPLIT_NAME(table.name, ' ')   AS name_parts

其他方言可能使用横向连接、不同的功能一起使用,或者可能根本没有功能。


编辑:内联表值函数的示例...

同样,这是特定于 SQL Server 的,不能推广到其他 DBMS...

CREATE FUNCTION [dbo].[SPLIT_NAME] (@name NVARCHAR(MAX))
RETURNS TABLE
AS
RETURN
  SELECT
    SUBSTRING(@name, 1, PATINDEX('% %',@name)            ) AS first_name,
    SUBSTRING(@name,    PATINDEX('% %',@name), LEN(@name)) AS last_name

它是内联的,因为没有开始/结束、过程语言等。它只是一个 SELECT 语句(可以有 FROM 子句,但不是必须的)和一些参数。

(我是在手机上写的,它可能在语法上并不完全正确,但演示了这个概念。)

【讨论】:

  • 谢谢,内联表值函数的例子是什么?
猜你喜欢
  • 2021-12-23
  • 2011-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-02
  • 1970-01-01
相关资源
最近更新 更多