sql 生成随机数 以及不重复随机数
背景:想在表中随机取10条记录,让取出来的数据不重复(表中必须是有个递增列,且递增从1开始间隔为1)。
数据表:
CREATE TABLE testable
(
id INT IDENTITY(1,1),
myname NVARCHAR(1000),
insertedTime DATETIME DEFAULT SYSDATETIME()
)
表中共有100条数据,如下
省略……
1. 首先想到的是MSSQL自带的newid()
采用这种方法时,需要将表中所有记录与newid()生成的值进行比较从而进行排序。因此,如果表中的记录较多,操作会非常缓慢。

USE Gift163DBgoSELECT TOP 14 * FROM dbo.testable ORDER BY NEWID()
缺点:1. 取出的10条数据会出现重复 2.当数据表数据很多的时候,速度将很慢 (每次重新计算newid)
2. 自定义函数返回一个表,表中记录的是随机生成的N个id值。
1)rand()生成随机数 rand()*count,CEILING,floor用法
2)如果临时表中无此数据,则放入,否则重新生成
3)直到N条记录已经生成
注意:标量函数function内不能出现rand()方法,变通下生成个view v_random,然后在函数内调用 v_random获取随机数
create view v_randomASselect CEILING(rand()*51) as random --注意51,生成的是1到51之间的数字,因为事先知道数据库中有51条记录go
自定义函数代码如下:
ALTER FUNCTION randomIntStringWithCommaSplit(@counts int) –counts 表明返回的个数RETURNS @t TABLE (filed1 int) --返回表@t,有个int类型的 field列ASBEGINDECLARE @randomInt INTDECLARE @i INTSET @i=0WHILE @i<@countsBEGINselect @randomInt= random FROM v_random--不能是 SET @randomInt=SELECT random FROM v_randomIF NOT EXISTS(SELECT TOP 1 * FROM @t WHERE filed1=@randomInt)BEGININSERT INTO @t VALUES (@randomInt)SET @i=@i+1ENDENDRETURNEND
上面函数返回的是一个表类型,表中有个int字段,存放要查找的N个不同的keyId (keyId为要查找表的递增列,且递增为1,从1开始递增)
所以返回的表中存放的数据是 dbo.Articles中的id列的值。
使用:调用上面的自定义函数返回10个不重复的id
SELECT * FROM randomIntStringWithCommaSplit(10)
下面是几次的执行结果,可以看到每个结果中都不存在重复的值(fidled1为临时表的唯一列)

最后通过 select * from table where id in randomIntStringWithCommaSplit(10) ,这样就可以从table中随机取出10条不重复的数据来了。
3.存储过程取不重复的数据
--dbo.getRandomDataFromTable
--输入参数 @tableName nvarchar(100),--表名
---@dataCount nvarchar(100)--取N条数据
输出结果集:列id,存放N条要查询的数据
USE Gift163DBGOIF OBJECT_ID ( 'dbo.getRandomDataFromTable', 'P' ) IS NOT NULLDROP PROCEDURE dbo.getRandomDataFromTable;GOCREATE PROC [dbo].[getRandomDataFromTable]@tableName nvarchar(100),@dataCount nvarchar(100)ASBEGIN--SET NOCOUNT ON;DECLARE @t TABLE (id INT) --临时表DECLARE @i INT --临时变量DECLARE @randomInt INT --每次随机生成的整数DECLARE @tableCount INT --表的行数--先获取表中最大数据的idEXEC( 'SELECT '+@tableCount+'=COUNT(*) FROM '+@tableName+'')SET @i=0WHILE @i<@dataCountBEGINSELECT @randomInt=CEILING(RAND()*@tableCount)IF NOT EXISTS(SELECT TOP 1 * FROM @t)BEGININSERT INTO @t VALUES (@randomInt)SET @i=@i+1ENDEND--打印出取出的表的idSELECT * FROM @tENDGo
生成测试数据100条
USE Gift163DBGOif exists (select 1from sysobjectswhere id = object_id('testable')and type = 'U')drop table testablegoCREATE TABLE testable(id INT IDENTITY(1,1),myname NVARCHAR(1000),insertedTime DATETIME DEFAULT SYSDATETIME())//插入100条数据DECLARE @i INTSET @i=1WHILE @i<100BEGININSERT INTO tesTable (myname) VALUES ('我的名字是'+CONVERT(NVARCHAR, @i) ) --将 varchar 值 '我的名字是' 转换成数据类型 int 时失败。SET @i=@i+1End
调用上面的存储过程从表testable取10条不重复id
USE Gift163DBgoexec getRandomDataFromTable 'testable',10

自定义的存储过程不会出现重复的记录
4.改进的存储过程,最终存储过程
输入参数3个:表名,表的递增列名 , 要取的N条数据
USE Gift163DBGOIF OBJECT_ID ( 'dbo.getRandomDataFromTable', 'P' ) IS NOT NULLDROP PROCEDURE dbo.getRandomDataFromTable;GOCREATE PROC [dbo].[getRandomDataFromTable]@tableName nvarchar(100),@identityKey NVARCHAR(100),@dataCount nvarchar(100)ASBEGIN--SET NOCOUNT ON;--DECLARE @t TABLE (id INT) --临时表DECLARE @i INT --临时变量DECLARE @randomInt INT --每次随机生成的整数DECLARE @tableCount INT --表的行数--先获取表中最大数据的idDECLARE @str NVARCHAR(3000)SET @str='SELECT @tableCount=COUNT(*) FROM '+@tableNameexec sp_executesql @str, N'@tableCount int output', @tableCount outputcreate TABLE #sdf (id int)SET @i=0WHILE @i<@dataCount AND @i<@tableCountBEGINSELECT @randomInt=CEILING(RAND()*@tableCount)IF NOT EXISTS(SELECT TOP 1 * FROM #sdf WHERE id=@randomInt)BEGININSERT INTO #sdf VALUES (@randomInt)SET @i=@i+1ENDEND--取出数据DECLARE @str2 NVARCHAR(2000)SET @str2=' SELECT * FROM '+@tableName+' where '+@identitykey+' in '+' (select id from #sdf )'PRINT @str2--select id from @tEXEC (@str2)--exec sp_executesql @str2,N'@t TABLE',@t OUTPUTEND
调用存储过程:随机取10条数据

最终的存储过程不管你随机取多少条数据(只要每次取的数据数目小于表中行数) 就可以保证每次取的数据不会重复。当然前提是,取的表必须有个递增列,而且以1开始,递增1.
sql 生成随机数 以及不重复随机数的更多相关文章
- 动态生成16位不重复随机数、随机创建2位ID
/** 1. * 动态生成16位不重复随机数 * * @return */ public synchronized static String generate16() { StringBuffer ...
- js【生成规定数量不重复随机数】、【冒泡排序】、【鸡尾酒排序】、【选择排序】、【插入排序】、【未完工的二分插入排序】------【总结】
[生成规定数量不重复随机数] function creatRandom( num ){ var randomLen = num, ranArr = [], thisRan = null, whileO ...
- sql 生成某个范围内的随机数
从i-j的范围内的随机数,那么公式为FLOOR(i+RAND()*(j-i+1))
- SQL - 生成指定范围内的随机数
今天按照公司需求,需要做一个sql作业来对数据库定时触发,其中有个难点,就是在sql中需要在1-n中随机出来一个结果. google了半天,找到一个比较好的方式. 写下这个sql: DECLARE @ ...
- 【转】 SQL - 生成指定范围内的随机数
DECLARE @Result INT DECLARE @Upper INT DECLARE @Lower INT SET @Lower = 1 SET @Upper = 10 SELECT @Res ...
- Java数组实现随机生成N-M之间不重复的随机数
接收一个整形数组,使用Math.Random每次在规定的数字范围内随机产生数字,然后嵌套for循环依次判断是否有重复值,如果有既外循环变量减一,直到把数组装满为止. /** * 随机生成 N--M的不 ...
- C#生成不重复随机数列表
C#生成不重复(随机数 http://www.jbxue.com/tags/suijishu.html)列表实例的代码.例子: ; Random rnd = ; i < ...
- PHP函数:生成N个不重复的随机数
思路:将生成的随机数存入数组,再在数组中去除重复的值,即可生成一定数量的不重复随机数. 程序: <?php /* * array unique_rand( int $min, int $max, ...
- [转载]C# Random 生成不重复随机数
Random 类 命名空间:System 表示伪随机数生成器,一种能够产生满足某些随机性统计要求的数字序列的设备. 伪随机数是以相同的概率从一组有限的数字中选取的.所选数字并不具有完全的随机性,因为它 ...
随机推荐
- 报错:PermissionError: [WinError 5] Access is denied: 'C:\\Program Files\\Anaconda3\\Lib\\site-packages\\pywebhdfs'
Outline 在本(Windows系统)地往 “PAI”(hdfs)上上传数据时,需要安装pywebhdfs包,然后就报错了: 报错信息: PermissionError: [WinError 5] ...
- Python3+Selenium3自动化测试-(一)
完成环境的安装并测试之后,我们对Selenium有了一定的了解了,接下来我们继续驱动浏览器做一些基本操作: 窗口尺寸设置.网页截图.刷新.前进和后退 窗口尺寸设置 在测试过程中,我们可能会要求打开浏览 ...
- tomcat访问管理页面出现:403 Access Denied 解决方法
点击红色框框出现以下403错误 打开context.xml文件 vim /usr/local/tomcat/webapps/manager/META-INF/context.xml <Conte ...
- html5.js让IE(包含IE6)支持HTML5元素方法
原文地址:http://blog.sina.com.cn/s/blog_62a36ec401018oqb.html html5.js让IE(包含IE6)支持HTML5元素方法 微软的最新浏览器IE8及 ...
- excel数据生成sql insert语句
excel表格中有A.B.C三列数据,希望导入到数据库users表中,对应的字段分别是name,sex,age . 在你的excel表格中增加一列,利用excel的公式自动生成sql语句,方法如下: ...
- (转)RTP-H264封包分析
rtp(H264)第一个包(单一NAL单元模式)————-sps 80 {V=10,p=0,x=0,cc=0000} 60 {m=0,pt=110 0000} 53 70{sequence numbe ...
- [设计模式]State模式
<Java与模式> 又称状态对象模式.状态模式是对象的行为模式.GOF95 一个对象的行为取决于一个或者多个动态变化的属性,这样的属性叫做状态.这样的对象叫做有状态的对象(stateful ...
- 前端基础之JavaScript(Day53)
阅读目录 一.JavaScript基础 二.JavaScript对象 三.BOM对象 一.JavaScript基础 http://www.cnblogs.com/yuanchenqi/articles ...
- Delphi 正则表达式之TPerlRegEx 类的属性与方法(7): Split 函数
Delphi 正则表达式之TPerlRegEx 类的属性与方法(7): Split 函数 //字符串分割: Split var reg: TPerlRegEx; List: TStrings; ...
- Xamrin开发安卓笔记(三)
http://www.cnblogs.com/minCS/p/4118170.html Xamrin开发安卓笔记(三) 安装片 Xamrin开发安卓笔记(一) Xamrin开发安卓笔记(二) 这次 ...