Sql server 函数返回范围内的奇数
我正在尝试使用CTE生成脚本内联值函数 如果我输入1,表格只显示奇数,当我输入n<11时,它显示1,3,5,7,9,11 此脚本显示从1到11的每一个数字。 我应该补充什么Sql server 函数返回范围内的奇数,sql-server,sql-server-2008,tsql,Sql Server,Sql Server 2008,Tsql,我正在尝试使用CTE生成脚本内联值函数 如果我输入1,表格只显示奇数,当我输入n
CREATE FUNCTION [dbo].[oddNumFunction]
(
@oddNum int
)
Returns TABLE
AS
RETURN
with R_table(n)
as
(
select @oddNum as n
union all
select n + 1 from R_table where n < 11
)
select * from R_table
试着这样做:
DECLARE @oddnum INT = 1;
WITH R_TABLE(N)
AS (SELECT @oddNum AS n
UNION ALL
SELECT N + 2
FROM R_TABLE
WHERE N < 11)
SELECT *
FROM R_TABLE
试着这样做:
DECLARE @oddnum INT = 1;
WITH R_TABLE(N)
AS (SELECT @oddNum AS n
UNION ALL
SELECT N + 2
FROM R_TABLE
WHERE N < 11)
SELECT *
FROM R_TABLE
与使用递归CTE相比,我会选择更简单的方法:
DECLARE @oddNum INT = 1;
SELECT number
FROM master..spt_values
WHERE [type] = N'P'
AND number % 2 = 1
AND number BETWEEN @oddNum AND 11;
另一种方法是,如果你有一个非常有用的数字表。它不必包含1000000行,这只是为了证明它可以。使用压缩,这需要11MB;没有,13MB
CREATE TABLE dbo.Numbers(number INT PRIMARY KEY)
WITH (DATA_COMPRESSION = PAGE); -- recommended if your edition supports it
INSERT dbo.Numbers(number) SELECT TOP (1000000)
ROW_NUMBER() OVER (ORDER BY s1.[object_id])
FROM sys.all_objects AS s1
CROSS JOIN sys.all_objects AS s2;
SELECT number FROM dbo.Numbers; -- prime it
当您使用它时,您可以使用SCHEMABINDING创建您的函数,这有额外的好处
现在:
因此,您的功能可以是:
CREATE FUNCTION [dbo].[oddNumFunction2]
(
@oddNum INT
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
(
SELECT number
FROM dbo.Numbers
WHERE number % 2 = 1
AND number BETWEEN @oddNum AND 11
);
性能比较,运行10000次并将输出填充到临时表中:
Gidil: 30.31 seconds
Mahmoud: 29.11 seconds
Me (spt_values): 27.91 seconds
Me (numbers): 28.06 seconds
原因是小的spt_值表已经在内存中,我们强制数字表在内存中,需要读取的逻辑数很少!比递归CTE的计算成本更低,即使是最多只生成6行的CTE
我很惊讶马哈茂德的测试结果比吉迪尔的快,但我运行了多次,结果是一致的。你可以试着自己测试并比较它们。虽然在大多数情况下,这种性能差异是可以忽略不计的,但我不会用手去挥动这些东西,如果我找到了我所知道的最有效的方法去做某事,我宁愿使用它,即使亚军紧随其后
如果您真的希望这是一个CTE,下面将处理给定任何输入奇数或偶数在0和11之间的奇数:
DECLARE @oddnum INT = 1;
;WITH n(n) AS
(
SELECT @oddNum + ((@oddNum-1)%2)
UNION ALL
SELECT n + 2 FROM n WHERE n < 11
)
SELECT n FROM n;
与使用递归CTE相比,我会选择更简单的方法:
DECLARE @oddNum INT = 1;
SELECT number
FROM master..spt_values
WHERE [type] = N'P'
AND number % 2 = 1
AND number BETWEEN @oddNum AND 11;
另一种方法是,如果你有一个非常有用的数字表。它不必包含1000000行,这只是为了证明它可以。使用压缩,这需要11MB;没有,13MB
CREATE TABLE dbo.Numbers(number INT PRIMARY KEY)
WITH (DATA_COMPRESSION = PAGE); -- recommended if your edition supports it
INSERT dbo.Numbers(number) SELECT TOP (1000000)
ROW_NUMBER() OVER (ORDER BY s1.[object_id])
FROM sys.all_objects AS s1
CROSS JOIN sys.all_objects AS s2;
SELECT number FROM dbo.Numbers; -- prime it
当您使用它时,您可以使用SCHEMABINDING创建您的函数,这有额外的好处
现在:
因此,您的功能可以是:
CREATE FUNCTION [dbo].[oddNumFunction2]
(
@oddNum INT
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
(
SELECT number
FROM dbo.Numbers
WHERE number % 2 = 1
AND number BETWEEN @oddNum AND 11
);
性能比较,运行10000次并将输出填充到临时表中:
Gidil: 30.31 seconds
Mahmoud: 29.11 seconds
Me (spt_values): 27.91 seconds
Me (numbers): 28.06 seconds
原因是小的spt_值表已经在内存中,我们强制数字表在内存中,需要读取的逻辑数很少!比递归CTE的计算成本更低,即使是最多只生成6行的CTE
我很惊讶马哈茂德的测试结果比吉迪尔的快,但我运行了多次,结果是一致的。你可以试着自己测试并比较它们。虽然在大多数情况下,这种性能差异是可以忽略不计的,但我不会用手去挥动这些东西,如果我找到了我所知道的最有效的方法去做某事,我宁愿使用它,即使亚军紧随其后
如果您真的希望这是一个CTE,下面将处理给定任何输入奇数或偶数在0和11之间的奇数:
DECLARE @oddnum INT = 1;
;WITH n(n) AS
(
SELECT @oddNum + ((@oddNum-1)%2)
UNION ALL
SELECT n + 2 FROM n WHERE n < 11
)
SELECT n FROM n;
这是您的解决方案,针对您的需求进行了修复:
CREATE FUNCTION [dbo].[oddNumFunction]
(
@oddNum int
)
Returns TABLE
AS
RETURN
with R_table(n)
as
(
--select @oddNum as n
SELECT CASE WHEN @oddNum%2=0 THEN @oddNum+1 ELSE @oddNum END AS n
union all
select n + 2 from R_table where n < 11
)
select * from R_table
这是您的解决方案,针对您的需求进行了修复:
CREATE FUNCTION [dbo].[oddNumFunction]
(
@oddNum int
)
Returns TABLE
AS
RETURN
with R_table(n)
as
(
--select @oddNum as n
SELECT CASE WHEN @oddNum%2=0 THEN @oddNum+1 ELSE @oddNum END AS n
union all
select n + 2 from R_table where n < 11
)
select * from R_table
n+2而不是n+1然后如果我放入@oddnum2,它将给出2,4,6…..当@oddNum%2=0时,将select@oddNum作为n替换为select CASE,然后当@oddNum%2=0时,将@oddNum+1 ELSE@oddNum END作为nn+2而不是n+1;如果我放入@oddnum2,它将给出2,4,6…..当@oddNum%2=0时,将select@oddNum作为n替换为select CASE@oddNum+1 ELSE@oddNum END作为nn@Dongmin为什么您必须使用递归CTE吗?这是学校的作业吗?否则,为什么会有人为的要求呢?来到SQL Server 2016,隐秘的CTE。。。避免与他人作伴;孤独是的,这是。因此,我想要线索:3课程材料中是否没有任何关于如何构建递归CTE的信息?讲师知道你在这里得到帮助吗?在课程材料中,它只提供了CTE的信息。我需要从网上找到线索。所以我需要信息:D@Dongmin为什么必须使用递归CTE?这是学校的作业吗?否则,为什么会有人为的要求呢?来到SQL Server 2016,隐秘的CTE。。。避免与他人作伴;孤独是的,这是。因此,我想要线索:3课程材料中是否没有任何关于如何构建递归CTE的信息?讲师知道你在这里得到帮助吗?在课程材料中,它只提供了CTE的信息。我需要从网上找到线索。所以我需要信息:D汉克斯:D帮了大忙汉克斯:D帮了大忙