转自:http://www.cnblogs.com/dzy863/p/5063558.html
工作中会遇到SQL Server模拟数据生成以及数值列值(如整型、日期和时间数据类型)随机填充等等任务,这些任务中都要使用到随机数。鉴于此,本文将对SQL Server中随机数的使用简单做个总结 。
 
T-SQL 随机有关的三个函数
    
    RAND([seed] 此函数生成从0到1之间随机 float 值(详细说明查看https://technet.microsoft.com/zh-cn/library/ms177610(v=sql.90).aspx)。

CHECKSUM ( * | expression [ ,...n ] ) 此函数生成按照表的某一行或一组表达式计算出来的int校验和值,CHECKSUM 用于生成哈希索引(详细说明查看https://technet.microsoft.com/zh-cn/library/ms189788(v=sql.90).aspx)。

    
NEWID ( ) 此函数生成 uniqueidentifier 类型的唯一值(详细说明查看https://technet.microsoft.com/zh-cn/library/ms190348(v=sql.90).aspx)。
生成任意一个随机数值(如整数、日期和时间数据类型)
 
    如果获得任意一个随机整数值?函数RAND生成的结果是float数据类型的,显然很难满足要求,不过可以通过对函数RAND的结果继续加工(比如其结果乘以某一个值保留整数部分等等)得到要求。很显然,函数CHECKSUM生成的结果是int数据类型,很容易满足我们的结果,不过其参数如果固定(表的某一行值相同或一组表达式值相同),那么其结果也是相同的。函数NEWID可以保证结果的唯一,但是其结果是unigueidentifer数据类型的。
从以上三个函数的结果值分析:函数RNAD和CHECKSUM的结果是能获得整数数值的。如果我们将函数NEWID的结果值作为函数CHECKSUM的参数,那么其每次生成的结果值都是不一样的int数据类型的数值。以下T-SQL代码如下:
SELECT CHECKSUM(NEWID()) AS CheckSumValue, CHECKSUM(NEWID()) AS CheckSumValue2;
GO
执行后的查询结果如下:
从上面的查询结果看到组合生成的整数数值都是9位数的,平时工作中大多使用的随机整数值都是不太大的且都是自然数(0和正整数的集合),这就要求限制随机生成的整数数值。可以使用函数ABS对其结果进行处理得到任意一个自然数。这样,组合一起来的格式就是这样的:ABS(CHECKSUM(NEWID()))。为了便于使用便于使用我们通过将其封装到函数中,但是函数NEWID又不能在函数中使用,那我们就要考虑其他的方式:将函数NEWID封装在单列单行的视图中。其定义视图的T-SQL代码如下:
 1 IF OBJECT_ID(N'dbo.vRandomGuid', 'V') IS NOT NULL
 2 BEGIN
 3     DROP VIEW dbo.vRandomGuid;
 4 END
 5 GO
 6
 7 --==================================
 8 -- 功能: 随机Guid视图
 9 -- 说明: 具体实现阐述
10 -- 作者: XXX
11 -- 创建: yyyy-MM-dd
12 -- 修改: yyyy-MM-dd XXX 修改内容描述
13 --==================================
14 CREATE VIEW dbo.vRandomGuid
15     --$Encode$--
16 AS
17     SELECT RandomGuid = NEWID();
18 GO
19
20 调用该视图的T-SQL代码如下:
21 SELECT TOP 1 RandomGuid
22 FROM dbo.vRandomGuid;
23 GO

执行后的查询结果如下:

        
生成整数区间内的任意一个随机整数
    
    上面的视图定义,我们继续讲解组合函数的进一步封装。我们先讲解如何限制随机生成的数值,取模运算可以实现生成在指定数值区间内的任意一个数值,例如:获取区间[3,5]内任意一个数字,我们设为区间的最小值为@intMin:3,最大值为@intMax,则该区间的间隔值为 @intMax - @intMin + 1: 5 - 3 + 1(3),那么针对任意的整数值设为为@intValue,然后对这个间隔值先进行取模运算在加上区间最小值,最后得到的值为: @intValue % (@intMax - @intMin + 1) + @intMin。如果@intValue为8,则结果值为5;如果@intValue为9,则结果值为3;如果@intValue为10,则结果值为4……
针对以上的分析我们封装的T-SQL代码如下:
 1  IF OBJECT_ID(N'dbo.ufn_RandNum', 'FN') IS NOT NULL
 2 BEGIN
 3     DROP FUNCTION dbo.ufn_RandNum;
 4 END
 5 GO
 6
 7 --==================================
 8 -- 功能: 获取区间内的任意一个随机数值
 9 -- 说明: 具体实现阐述
10 -- 作者: XXX
11 -- 创建: yyyy-MM-dd
12 -- 修改: yyyy-MM-dd XXX 修改内容描述
13 -- 调用: SELECT dbo.ufn_RandNum(0, 1);
14 --==================================
15 CREATE FUNCTION dbo.ufn_RandNum
16 (
17     @intMin INT,            -- 随机数值的最小值
18     @intMax INT                -- 随机数值的最大值
19 ) RETURNS INT
20     --$Encode$--
21 AS
22 BEGIN
23     SET @intMin = ISNULL(@intMin, 0);
24     SET @intMax = ISNULL(@intMax, 0);
25
26     DECLARE @guidValue AS UNIQUEIDENTIFIER;
27
28     SELECT TOP 1 @guidValue = RandomGuid
29     FROM dbo.vRandomGuid;
30
31     RETURN ABS(CHECKSUM(@guidValue)) % (@intMax - @intMin + 1) + @intMin;
32 END
33 GO

调用以上函数的T-SQL代码如下:
1 SELECT dbo.ufn_RandNum(0, 1) AS RandNum, dbo.ufn_RandNum(10, 11) AS RandNum2;
2 GO

执行后的查询结果如下:
生成日期区间内的任意一个随机日期
那么我们继续讲解 获取指定区间内的任意一个随机日期,不过我们要使用日期和时间的两个函数:DATEADD和DATEDIFF。使用DATEDIFF计算出日期区间的间隔值,同上的思路我们计算得到的一个随机整数值,然后通过DATEADD得到我们期望的一个随机日期。封装函数的T-SQL代码如下:
 1 IF OBJECT_ID(N'dbo.ufn_RandDate', 'FN') IS NOT NULL
 2 BEGIN
 3     DROP FUNCTION dbo.ufn_RandDate;
 4 END
 5 GO
 6
 7 --==================================
 8 -- 功能: 获取日期区间内的任意一个随机日期
 9 -- 说明: 具体实现阐述
10 -- 作者: XXX
11 -- 创建: yyyy-MM-dd
12 -- 修改: yyyy-MM-dd XXX 修改内容描述
13 -- 调用: SELECT @dtmRand = dbo.ufn_RandDate('2007-02-01', '2007-03-01');
14 --==================================
15 CREATE FUNCTION dbo.ufn_RandDate
16 (
17     @dtmMin DATETIME,    -- 随机日期的最小值
18     @dtmMax DATETIME    -- 随机日期的最大值
19 ) RETURNS DATETIME
20     --$Encode$--
21 AS
22 BEGIN
23     SET @dtmMin = ISNULL(@dtmMin, '2000-01-01');
24     SET @dtmMax = ISNULL(@dtmMax, '2000-01-01');
25     DECLARE @guidVue AS UNIQUEIDENTIFIER;
26
27     SELECT TOP 1 @guidVue = RandomGuid
28     FROM dbo.vRandomGuid;
29
30     -- 可以将HOUR换为DAYS
31     RETURN DATEADD(HOUR, (ABS(CHECKSUM(@guidVue)) % (1 + DATEDIFF(HOUR, @dtmMax, @dtmMin))), @dtmMin);
32 END
33 GO

调用以上函数的T-SQL代码如下:
1 SELECT dbo.ufn_RandDate('2015-12-01', '2015-12-21') AS RandDate, dbo.ufn_RandDate('2016-12-01', '2016-12-21') AS RandDate2;
2 GO

执行后的查询结果如下:

区间随机数获取的扩展思考
无论是获取数值区间内的随机数值,还是日期区间内的随机日期,我们都使用了视图vRandomGuid。如果有一个连续的数值序列,我们通过查询这个数值序列,结合我们的区间数值和随机排序,也可以实现以上的效果。
假设该数值序列为SeqDataTable(Num INT),数值区间[@intMin,@intMax],那么该数值区间任意一个随机数值的T-SQL代码如下:
1 SELECT TOP 1 Num
2 FROM dbo.SeqDataTable
3 WHERE Num BETWEEN @intMin AND @intMax
4 ORDER BY NEWID() ASC;
5 GO

当然也可以利用以上的数字序列SeqDataTable(Num INT),日期区间[@dtmMin,@dtmMax],那个该数字区间任意一个随机日期的T-SQL代码如下:

1 SELECT TOP 1 DATEADD(DAY, Num, @dtmMin)
2 FROM dbo.SeqDataTable
3 WHERE Num BETWEEN 0 AND DATEDIFF(DAY, @dtmMin, @dtmMax)
4 ORDER BY NEWID() ASC;
5 GO

注意:以上代码无法执行成功的,也算是伪代码的。

    以后会针对数字序列有专门的详细讲解,这儿暂时作为一个扩展思考吧。
补充数字辅助表
  获取指定范围的任意一个数字的T-SQL代码如下:
1 SELECT TOP 1 Num
2 FROM dbo.ufn_GetNums(@bintMin, @bintMax)
3 ORDER BY NEWID() ASC;
4 GO
5
6 SELECT TOP 1 Num
7 FROM dbo.ufn_GetNums(11, 15)
8 ORDER BY NEWID() ASC;
9 GO

获取指定范围的任意一个日期的T-SQL代码如下:

1 SELECT TOP 1 DATEADD(DAY, Num, @dtmMin)
2 FROM dbo.ufn_GetNums(0, DATEDIFF(DAY, @dtmMax, @dtmMin))
3 ORDER BY NEWID() ASC;
4 GO
5
6 SELECT TOP 1 DATEADD(DAY, Num, '2015-12-01')
7 FROM dbo.ufn_GetNums(0, DATEDIFF(DAY, '2015-12-01', '2015-12-05'))
8 ORDER BY NEWID() ASC;
9 GO

以上代码中的表函数ufn_GetNums可以参看这篇博文SQL Server数字辅助表的实现

参考清单列表
https://technet.microsoft.com/zh-cn/library/ms177563(v=sql.90).aspx
https://technet.microsoft.com/zh-cn/library/ms177610(v=sql.90).aspx
https://technet.microsoft.com/zh-cn/library/ms189788(v=sql.90).aspx
https://technet.microsoft.com/zh-cn/library/ms190348(v=sql.90).aspx

http://www.cnblogs.com/chenxizhang/archive/2009/06/26/1511898.html
博友如有其他更好的解决方案,也请不吝赐教,万分感谢。

[MSSQL]SQL Server中的RAND函数的介绍和区间随机数值函数的实现相关推荐

  1. mysql的datepart函数_MySQL中的 DATE_FORMAT 与 SQL Server中的 DATEPART()函数使用介绍

    本小白最近学习MySQL,因为之前是已经有学过微软大佬的SQL Server所以自认为理解的还是稍快的(滑鸡),好了说正事. 今天在写一个查询语句时,需要用到 一个日期函数:DATEPART( ) 因 ...

  2. SQL Server中的STRING_SPLIT函数

    This article will cover the STRING_SPLIT function in SQL Server including an overview and detailed u ...

  3. percent sql_使用SQL Server中的PERCENT_RANK函数计算SQL百分位数

    percent sql This article explores the SQL Server PERCENT_RANK analytical function to calculate SQL P ...

  4. SQL Server中追踪器Trace的介绍和简单使用

    原文:SQL Server中追踪器Trace的介绍和简单使用 一.What is Trace? 对于SQL Profiler这个工具相信大家都不是很陌生,没用过的朋友可以在SQL Server Man ...

  5. sql游标 while_用SQL Server中的排名函数替换SQL While循环和游标,以提高查询性能

    sql游标 while SQL While loop and cursor are the most common approach to repeat a statement on conditio ...

  6. SQL SERVER中的方差函数

    1.偏差:一组数据偏离其平均数的值 2.方差:各个偏差的平方的平均数 3.标准偏差:方差的平方根 SQL SERVER中关于方差的函数: 1.STDEV 返回给定表达式中所有值的统计标准偏差. 2.S ...

  7. SQL Server中的Replicate函数。循环字符次数,可用于多层分类

    描述 REPLICATE :以指定的次数重复字符表达式. 语法 REPLICATE ( character_expression , integer_expression ) 参数 character ...

  8. SQL Server中字符串处理函数

    SQL Server中截取字符串常用函数 截取字符串中的最后一个斜杠后的所有字符: SELECT A.PIC_URL, RIGHT(A.PIC_URL,(CHARINDEX('/',REVERSE(A ...

  9. SQL Server中的四舍五入函数ROUND

    目录 目录 通过函数ROUND四舍五入 通过函数ROUND截断 参考资料 通过函数ROUND四舍五入 在SQL Server中若想完成四舍五入,可使用函数ROUND.如下是对函数ROUND的使用的简单 ...

最新文章

  1. R语言ggplot2可视化:使用gganimate包和gapminder包为生成的动画文件gif设置尺寸、分辨率
  2. python3实现下载ftp上的文件
  3. 【知识星球】颜值,自拍,美学三大任务简介和数据集下载
  4. 怎样利用好单片机上的存储器资源来实现OD的存储与访问
  5. Microsoft Jet SQL 参考在线手册
  6. Android中使用logwrapper来重定向应用程序的标准输出
  7. transaction缩写为什么是tx_TX Transaction locks常见的4种情况
  8. 使用CROS解决跨域问题
  9. RMQ with Shifts
  10. python 文本框内容变化_当文本框中的文本发生变化时,动态读取文本输入中的文本?...
  11. vs code 的便捷使用
  12. 字符串统计--对于给定的一个字符串,统计其中数字字符出现的次数。
  13. vs2010使用svn--浅谈AnkhSvn
  14. 最简单PS双重曝光效果制作教程
  15. 如何接收谷歌账号的注册短信
  16. html 网页公式编辑软件,LaTeX 公式编辑器网页版
  17. 修心修行“十一字”真言
  18. python实践报告的心得体会_动物医学实践报告心得体会
  19. 微信PC端浏览器内置浏览器
  20. 全国省级常住人口搜集指南

热门文章

  1. 国家级AI大赛王者之争:中国人工智能大赛·语言与知识技术竞赛团体赛完美收官
  2. Android APP:Preference使用详解和实例(附源码)
  3. Neil·Zou 语录二
  4. Linux下设置后台启动nohup命令
  5. Android settings中BT介绍
  6. Ubuntu 下的一些软件安装
  7. 谭笑鸿(字德馨)”取名详解
  8. c语言数组输入4个学生3门课成绩,编程题 从键盘输入4个学生和3门课的成绩至数组中,并求出每个学生3门课的平均成绩。...
  9. 如何在MySQL中导入SQL文件
  10. 如何从数据库中筛选出达成指定里程碑节点的项目_复盘|项目管理实战经验总结...