表函数
表函数(也称为表值函数 (TVF))是用户定义的函数,表函数会返回表。您可以在可使用表的任何位置使用表函数。表函数的行为与视图类似,但表函数可以接受参数。
创建表函数
要创建表函数,请使用 CREATE TABLE FUNCTION
语句。表函数包含生成表的查询。函数会返回查询结果。以下表函数接受 INT64
参数,并在针对名为 bigquery-public-data.usa_names.usa_1910_current
的公共数据集的查询中的 WHERE
子句内使用此值:
CREATE OR REPLACE TABLE FUNCTION mydataset.names_by_year(y INT64) AS ( SELECT year, name, SUM(number) AS total FROM `bigquery-public-data.usa_names.usa_1910_current` WHERE year = y GROUP BY year, name );
如需以其他方式进行过滤,您可以将多个参数传递给表函数。以下表函数按年份和名称前缀过滤数据:
CREATE OR REPLACE TABLE FUNCTION mydataset.names_by_year_and_prefix( y INT64, z STRING) AS ( SELECT year, name, SUM(number) AS total FROM `bigquery-public-data.usa_names.usa_1910_current` WHERE year = y AND STARTS_WITH(name, z) GROUP BY year, name );
表参数
您可以将 TVF 参数设置为表。在表参数名称之后,您必须明确指定所需的表架构,方法与指定结构体的字段相同。您传递给 TVF 的表参数可以包含参数架构中指定的列以外的其他列,并且这些列可以按任意顺序显示。
以下表函数会返回一个表,其中包含来自 orders
表的 item_name
的总销售额:
CREATE TABLE FUNCTION mydataset.compute_sales ( orders TABLE<sales INT64, item STRING>, item_name STRING) AS ( SELECT SUM(sales) AS total_sales, item FROM orders WHERE item = item_name GROUP BY item );
参数名称
如果表函数参数与表列的名称相匹配,则可能会产生有歧义的引用。在这种情况下,BigQuery 会将名称解释为对表列(而不是参数)的引用。建议您使用与任何引用的表列名称不同的参数名称。
使用表函数
您可以在表在其中有效的任何上下文中调用表函数。以下示例在 SELECT
语句的 FROM
子句中调用 mydataset.names_by_year
函数:
SELECT * FROM mydataset.names_by_year(1950)
ORDER BY total DESC
LIMIT 5
结果如下所示:
+------+--------+-------+
| year | name | total |
+------+--------+-------+
| 1950 | James | 86447 |
| 1950 | Robert | 83717 |
| 1950 | Linda | 80498 |
| 1950 | John | 79561 |
| 1950 | Mary | 65546 |
+------+--------+-------+
您可以将一个表函数的输出与另一个表联接:
SELECT *
FROM `bigquery-public-data.samples.shakespeare` AS s
JOIN mydataset.names_by_year(1950) AS n
ON n.name = s.word
您还可以在子查询中使用表函数:
SELECT ARRAY(
SELECT name FROM mydataset.names_by_year(1950)
ORDER BY total DESC
LIMIT 5)
调用具有表参数的表函数时,您必须在表参数名称前使用 TABLE
关键字。表参数可以包含表参数架构中未列出的列:
CREATE TABLE FUNCTION mydataset.compute_sales ( orders TABLE<sales INT64, item STRING>, item_name STRING) AS ( SELECT SUM(sales) AS total_sales, item FROM orders WHERE item = item_name GROUP BY item ); WITH my_orders AS ( SELECT 1 AS sales, "apple" AS item, 0.99 AS price UNION ALL SELECT 2, "banana", 0.49 UNION ALL SELECT 5, "apple", 0.99) SELECT * FROM mydataset.compute_sales(TABLE my_orders, "apple"); /*-------------+-------+ | total_sales | item | +-------------+-------+ | 6 | apple | +-------------+-------*/
列出表函数
表函数是一种例程。如需列出数据集中的所有例程,请参阅列出例程。
删除表函数
如需删除表函数,请使用 DROP TABLE FUNCTION
语句:
DROP TABLE FUNCTION mydataset.names_by_year
向例程授权
您可以将表函数授权为例程。借助授权例程,您可以与特定用户或群组共享查询结果,而无需为其授予生成结果的底层表的访问权限。例如,已获授权的例程可以计算对数据的聚合,也可以查找表值并在计算中使用该值。如需了解详情,请参阅已获授权的例程。
限制
查询正文必须是
SELECT
语句,并且不能修改任何内容。例如,表函数中不允许使用数据定义语言 (DDL) 和数据操纵语言 (DML) 语句。如果您需要副作用,请考虑改为编写过程。表函数必须与其引用的表存储在同一位置。
配额
如需详细了解表函数配额和限制,请参阅配额和限制。