我在SQL Server中模拟PostgreSQL样式generate_series()
表值函数:
CREATE FUNCTION generate_series(@d1 DATE, @d2 DATE)
RETURNS TABLE AS
RETURN
-- Ignore implementation (returning a single DATE column) for this question
现在可以按预期使用:
SELECT *
FROM generate_series(
CAST ('2005-07-01' AS DATE),
CAST ('2005-07-31' AS DATE)
) t
现在,我想使用派生列列表语法将列重命名为表格,如下所示:
SELECT *
FROM generate_series(
CAST ('2005-07-01' AS DATE),
CAST ('2005-07-31' AS DATE)
) t(col)
产生此错误:
Msg 195,Level 15,State 15,Line 5
' generate_series'不是公认的功能名称。
...而这种语法(限定功能)......
SELECT *
FROM dbo.generate_series(
CAST ('2005-07-01' AS DATE),
CAST ('2005-07-31' AS DATE)
) t(col)
...正在产生此错误:
Msg 317,Level 16,State 1,Line 5
表值函数" generate_series'不能有列别名。
在我看来,这种语法完全有效。它以这种方式在PostgreSQL,标准SQL和普通"中运行。也是T-SQL,例如:
SELECT *
FROM (
VALUES (1),(2)
) t(col)
我做错了什么?我怎么能实现这个目标? (I'm aware of the possibility of emulating this,但我真的想使用派生列列表语法。)
我正在使用SQL Server Express 2014
答案 0 :(得分:2)
SELECT *
FROM
(
SELECT *
FROM dbo.generate_series(
CAST ('2005-07-01' AS DATE),
CAST ('2005-07-31' AS DATE)
)) t(col)
我猜是因为虽然dbo.generate_series是一个函数,但它返回一个表。这样:
SELECT *
FROM
TableName t(Col)
无效
但是
SELECT *
FROM
(
SELECT *
FROM
TableName t
) t(col)
可行吗
所以换句话说,Derived Columns列表可以使用派生表,但不能在表派生时使用吗?
我认为我首选的语法是使用列别名而不是派生列列表。
SELECT d as Col
FROM
dbo.generate_series(
CAST ('2005-07-01' AS DATE),
CAST ('2005-07-31' AS DATE)
) t
答案 1 :(得分:2)
在这种情况下,您无法添加列别名。这不是使用表值构造函数,而是从表值函数返回。只需删除列别名即可。
SELECT *
FROM dbo.generate_series(
CAST ('2005-07-01' AS DATE),
CAST ('2005-07-31' AS DATE)
) t
FWIW,我建议在你的函数中使用计数表而不是递归cte。如果您的日期范围很长,性能将受到影响,因为您实际上正在使用rcte进行计数。如果检查执行计划,它与while循环相同。杰夫莫登有一篇很棒的文章详细讨论了这个问题。 http://www.sqlservercentral.com/articles/T-SQL/74118/
- 编辑 -
要创建别名,您不能简单地添加别名吗?
SELECT t.d as MyAlias
FROM dbo.generate_series(
CAST ('2005-07-01' AS DATE),
CAST ('2005-07-31' AS DATE)
) t
答案 2 :(得分:1)
from子句的相关部分在这里。
column_alias
仅支持派生表和@variable.function_call
[ FROM { <table_source> } [ ,...n ] ]
<table_source> ::=
{
table_or_view_name [ [ AS ] table_alias ]
[ <tablesample_clause> ]
[ WITH ( < table_hint > [ [ , ]...n ] ) ]
| rowset_function [ [ AS ] table_alias ]
[ ( bulk_column_alias [ ,...n ] ) ]
| user_defined_function [ [ AS ] table_alias ]
| OPENXML <openxml_clause>
| derived_table [ [ AS ] table_alias ] [ ( column_alias [ ,...n ] ) ]
| <joined_table>
| <pivoted_table>
| <unpivoted_table>
| @variable [ [ AS ] table_alias ]
| @variable.function_call ( expression [ ,...n ] )
[ [ AS ] table_alias ] [ (column_alias [ ,...n ] ) ]
| FOR SYSTEM_TIME <system_time>
}
所以,至少目前,你需要包装user_defined_function
电话。例如在派生表或CTE中对列进行别名。