1. 程式人生 > >sql 生成隨機數 以及不重複隨機數

sql 生成隨機數 以及不重複隨機數

背景:想在表中隨機取10條記錄,讓取出來的資料不重複(表中必須是有個遞增列,且遞增從1開始間隔為1)。 

資料表:

CREATE TABLE testable 

id INT  IDENTITY(1,1), 
myname  NVARCHAR(1000), 
insertedTime DATETIME DEFAULT SYSDATETIME() 
)

表中共有100條資料,如下

image 省略……

1.     首先想到的是MSSQL自帶的newid()

採用這種方法時,需要將表中所有記錄與newid()生成的值進行比較從而進行排序。因此,如果表中的記錄較多,操作會非常緩慢。

image

USE  Gift163DB
go
SELECT  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_random
AS
   select CEILING(rand()*51) as random    --注意51,生成的是1到51之間的數字,因為事先知道資料庫中有51條記錄
go

自定義函式程式碼如下:

ALTER FUNCTION  randomIntStringWithCommaSplit(@counts int) –counts 表明返回的個數
          
RETURNS @t TABLE (filed1 int)  --返回表@t,有個int型別的 field列
AS
BEGIN
  DECLARE @randomInt INT
  SET
@i=0
        WHILE @i<@counts
        BEGIN
                 select @randomInt= random FROM v_random
          --不能是 SET @randomInt=SELECT random FROM v_random
          IF NOT EXISTS(SELECT TOP 1 * FROM @t WHERE [email protected])
           BEGIN
             INSERT INTO @t VALUES (@randomInt)
             SET @[email protected]+1
           END
        END
END

上面函式返回的是一個表型別,表中有個int欄位,存放要查詢的N個不同的keyId  (keyId為要查詢表的遞增列,且遞增為1,從1開始遞增)

所以返回的表中存放的資料是 dbo.Articles中的id列的值。

使用:呼叫上面的自定義函式返回10個不重複的id

SELECT * FROM randomIntStringWithCommaSplit(10)

下面是幾次的執行結果,可以看到每個結果中都不存在重複的值(fidled1為臨時表的唯一列)

image image image image image

最後通過  select * from table  where id in  randomIntStringWithCommaSplit(10) ,這樣就可以從table中隨機取出10條不重複的資料來了。

3.儲存過程取不重複的資料

--dbo.getRandomDataFromTable 
--輸入引數  @tableName  nvarchar(100),--表名 
[email protected]  nvarchar(100)--取N條資料

輸出結果集:列id,存放N條要查詢的資料

USE Gift163DB
GO
IF OBJECT_ID ( 'dbo.getRandomDataFromTable', 'P' ) IS NOT NULL 
    DROP PROCEDURE dbo.getRandomDataFromTable;
GO
CREATE PROC  [dbo].[getRandomDataFromTable]
@tableName  nvarchar(100),
@dataCount  nvarchar(100)
AS
BEGIN
  --SET NOCOUNT ON;
    DECLARE @t TABLE (id INT)   --臨時表
    DECLARE @i  INT             --臨時變數
    DECLARE @randomInt INT      --每次隨機生成的整數
    DECLARE @tableCount INT     --表的行數
    --先獲取表中最大資料的id
   EXEC(  'SELECT '[email protected]+'=COUNT(*) FROM  '[email protected]+'')
    SET @i=0
    WHILE @i<@dataCount
    BEGIN
      SELECT @randomInt=CEILING(RAND()*@tableCount)
      IF NOT EXISTS(SELECT TOP 1 * FROM @t)
      BEGIN
          INSERT INTO @t VALUES (@randomInt)
          SET @[email protected]+1
      END
    END
    --打印出取出的表的id
END
Go

生成測試資料100條

USE Gift163DB
GO
            from  sysobjects
           where  id = object_id('testable')
            and   type = 'U')
   drop table testable
go
CREATE TABLE testable
(
myname  NVARCHAR(1000),
insertedTime DATETIME DEFAULT SYSDATETIME()
)
//插入100條資料
SET @i=1
WHILE @i<100
BEGIN
  INSERT INTO tesTable (myname) VALUES ('我的名字是'+CONVERT(NVARCHAR, @i) )   --將 varchar 值 '我的名字是' 轉換成資料型別 int 時失敗。
  SET @[email protected]+1
End

呼叫上面的儲存過程從表testable取10條不重複id

USE Gift163DB
go
 exec    getRandomDataFromTable  'testable',10

image image image

自定義的儲存過程不會出現重複的記錄

4.改進的儲存過程,最終儲存過程

輸入引數3個:表名,表的遞增列名 , 要取的N條資料

USE Gift163DB
GO
IF OBJECT_ID ( 'dbo.getRandomDataFromTable', 'P' ) IS NOT NULL 
    DROP PROCEDURE dbo.getRandomDataFromTable;
GO
CREATE PROC  [dbo].[getRandomDataFromTable]
@tableName  nvarchar(100),
@identityKey NVARCHAR(100),
@dataCount  nvarchar(100)
AS
BEGIN
  --SET NOCOUNT ON;
    --DECLARE @t TABLE (id INT)   --臨時表
    DECLARE @i  INT             --臨時變數
    DECLARE @randomInt INT      --每次隨機生成的整數
    DECLARE @tableCount INT     --表的行數
    --先獲取表中最大資料的id
   SET @str='SELECT @tableCount=COUNT(*) FROM  '[email protected]
   exec sp_executesql @str, N'@tableCount int output', @tableCount output
   create TABLE #sdf (id int)
    SET @i=0
    WHILE @i<@dataCount AND @i<@tableCount
    BEGIN
      SELECT @randomInt=CEILING(RAND()*@tableCount)
      IF NOT EXISTS(SELECT TOP 1 * FROM #sdf WHERE [email protected])
      BEGIN
          INSERT INTO #sdf VALUES (@randomInt)
          SET @[email protected]+1
      END
    
            
           

相關推薦

sql 生成隨機數 以及重複隨機數

背景:想在表中隨機取10條記錄,讓取出來的資料不重複(表中必須是有個遞增列,且遞增從1開始間隔為1)。  資料表: CREATE TABLE testable  (  id INT  IDENTITY(1,1),  myname  NVARCHAR(1000),  insertedTime DATETIME

生成N位重複隨機數

package com.jack.question.random; import java.util.Arrays; import java.util.Random; /** * @author lvh */ public class RandomArray { /* * 如題,定義一

生成重複隨機數序列(Java)

從1到n之間抽取出k個不重複的隨機數,用Math.random()實現的話,可參照下面的程式碼。 int r = (int) (Math.random() * n), 生成下標,據此下標,去到numbers數組裡拿到隨機數。然後將numbers[r]的值設定成

[js][技巧]生成指定範圍指定個數的重複隨機數

今天偶然看到的 比如要生成 1-100範圍之內的10個不重複隨機數,程式碼就可以這麼寫 var arr = []; for (var i = 1; i <=100; i++) { arr.push(i); } arr.sort(

生成重複隨機數,自己寫的,嘿嘿

package 基礎演算法; import java.util.Arrays; public class radomNums { public static void main(String[] args){ int[] array=new int[8]; i

Delphi 中生成指定範圍重複隨機數

剛開始學習Dephi,寫這個相當於學習筆記,有不正確的地方,請各位大神多多指教 生成指定範圍的不重複大的隨機數  指定隨機數的範圍,生成不重複的隨機數 while si < sum do                    //si 表示生成隨機數的個數  

Jmeter生成8位重複隨機數

要求:對註冊介面進行100000次壓測,手機號已126開頭,後面的8位數不限   前言:在進行測試中,我們需要對註冊介面進行壓測100000次,那麼就要求手機號碼每次填寫的不一致,否則手機號使用一次後會出現該手機號碼已註冊的情況,為了避免這種情況的發生,我們對手機號碼的

PHP高效生成一個重複隨機數

PHP高效產生m個n範圍內的不重複隨機數(m<=n) 注:在《 Programming Pearls 》一書中也有提到,題目為“如何高效產生m個n範圍內的不重複隨機數(m<=n)” 該演算法非常巧妙的取隨機數的位置(陣列的下標),替代取隨機數本身,每次取到一個隨機數之後,就將其在取值範圍

mysql生成重複隨機數(unique number generation)

問題來源 業務中有時會遇到要生成不重複隨機數的情況,例如,新生成一個商品編號、房間編號、或者其他物品編號等。不願意採用表的自增索引 id,同時又希望新生成的編號是不重複的。 這就需要考驗mysql的隨機數功能了。 Solution mysql的rand函

生成N個重複隨機數

<?php /* * array unique_rand( int $min, int $max, int $num ) * 生成一定數量的不重複隨機數 * $min 和 $max: 指定隨機數

生成重複隨機數的方法 --抽獎問題等

問題描述: 給定一個n,一個m 要求在1 ~ n這n個數字中,生成m個不重複的隨機數。 思路: 生成隨機數大家都知道,C++中也提供了相關的函式——rand()。 但是問題中要求生成的是無重複的隨機數,這裡就需要對生成的隨機數進行去重操作了。 首選最

C# Random 生成重複隨機數

名稱空間:System 表示偽隨機數生成器,一種能夠產生滿足某些隨機性統計要求的數字序列的裝置。 偽隨機數是以相同的概率從一組有限的數字中選取的。所選數字並不具有完全的隨機性,因為它們是用一種確定的數學演算法選擇的,但是從實用的角度而言,其隨機程度已足夠了。 偽隨機數的

ios 生成重複隨機數

一、先講下ios三種取隨機數的方法: 1.    srand((unsigned)time(0));  //不加這句每次產生的隨機數不變        int i = rand() % 5;   

C#中生成重複隨機數

如果只是生成一個隨機數,C#中的Random函式就足夠用了,但如果需要生產若干個隨機數,且這些數不能重複,就需要自己來寫相應的方法了。 1.使用List<int>來儲存隨機數,List.Contain方法來判斷生成的隨機數是否已經存在 以在1-10中取5個不重複

PHP 生成一定數量的重複隨機數

將隨機數存入陣列,再在陣列中去除重複的值,即可生成一定數量的不重複隨機數。 function unique_rand($min, $max, $num) {$count = 0;$return = array();while ($count < $num) {$r

生成重複隨機數的演算法(其一)

背景: 隨機生成點菜選單,其中一個需求是不重複取隨機數。 在網上看到一個比較好的演算法,記錄如下: import java.util.Random; public class test { private static int RANGE = 10; privat

set生成重複隨機數

“ES6對js提供了各種合乎程式設計規範的拓展,給開發工作帶來了極大的便利。減少可開發過程中製造工具函式的耗費,同時減少對第三方工具函式庫的依賴。本系列的筆記,主要是記錄日常開發中常用的ES6使用方法。

jq生成重複隨機數

酒逢知己千杯少,話不投機半句多,直接上程式碼 程式碼 var arr = [];//存放隨機數的陣列 var arrLen = 5;//陣列長度,也用來限制範圍 for(var i=0; i<arrLen; i++){

[Java]重複隨機數生成簡易演算法

方法一 通過單個數組簡易實現不重複隨機數生成,先上原始碼。 /** * 獲取隨機陣列 * @param 源陣列 * @param size 目標陣列大小 * @return 隨機陣列 */ public static int[] getRandomRe

oracle生成重複隨機數

1.建立FUNCTION fn_ifrandom(其中用到遞迴) CREATE OR REPLACE FUNCTION fn_ifrandom (tmpallrandom IN clob,tmprandom IN VARCHAR2,allcount in number)