栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 数据库 > SQL Server

SqlServer 2005 T-SQL Query 学习笔记(4)

SQL Server 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SqlServer 2005 T-SQL Query 学习笔记(4)

比如,我要建立一个1,000,000行的数字表:

CREATE TABLE dbo.Nums(n INT NOT NULL PRIMARY KEY);
DECLARE @max AS INT, @rc AS INT;
SET @max = 1000000;
SET @rc = 1;

INSERT INTO Nums VALUES(1);
WHILE @rc * 2 <= @max
BEGIN
INSERT INTO dbo.Nums SELECt n + @rc FROM dbo.Nums;
SET @rc = @rc * 2;
END

INSERT INTO dbo.Nums
SELECt n + @rc FROM dbo.Nums WHERe n + @rc <= @max;
这种方式非常巧妙,它并不是一个一个的循环插入,而是一次插入很多行,{1},{2},{3,4},{5,6,7,8}。。。 为什么这样会快呢?

是因为它节省了跟比较其他可用解决方案进行比较和记录这些日志的时间。 然后,作者给了一个CTE的递归的解决方案:

DECLARE @n AS BIGINT;
SET @n = 1000000;

WITH Nums AS
(
SELECt 1 AS n
UNIOn ALL
SELECT n + 1 FROM Nums WHERe n < @n
)
SELECt n FROM Nums
OPTION(MAXRECURSION 0);--为了移除默认100的递归限制


有个更优的CTE的解决方案,就是先生成很多行,然后用ROW_NUMBER进行计算,再选择ROW_NUMBER这列的值就可以了。

复制代码 代码如下:
DECLARE @n AS BIGINT;
SET @n = 1000000;

WITH base AS
(
SELECt 1 AS n
UNIOn ALL
SELECT n + 1 FROM base WHERe n < CEILING(SQRT(@n))
),
Expand AS
(
SELECt 1 AS c
FROM base AS B1, base AS B2
),
Nums AS
(
SELECt ROW_NUMBER() OVER(ORDER BY c) AS n
FROM Expand
)
SELECt n FROM Nums WHERe n <= @n
OPTION(MAXRECURSION 0);


利用笛卡尔积进行不断的累加,达到了22n行。

最后,作者给出了一个函数,用于生成这样的数字表:
复制代码 代码如下:
CREATE FUNCTION dbo.fn_nums(@n AS BIGINT) RETURNS TABLE
AS
RETURN
WITH
L0 AS(SELECt 1 AS c UNIOn ALL SELECT 1),
L1 AS(SELECT 1 AS c FROM L0 AS A, L0 AS B),
L2 AS(SELECt 1 AS c FROM L1 AS A, L1 AS B),
L3 AS(SELECt 1 AS c FROM L2 AS A, L2 AS B),
L4 AS(SELECt 1 AS c FROM L3 AS A, L3 AS B),
L5 AS(SELECt 1 AS c FROM L4 AS A, L4 AS B),
Nums AS(SELECt ROW_NUMBER() OVER(ORDER BY c) AS n FROM L5)
SELECt n FROM Nums WHERe n <= @n;
GO
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/172669.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号