SQL中的随机函数-笔记
僅為個人學習筆記
ABS函數
在數據庫獲取數據時通常會遇到負數的情況,但客戶要求的是不能有負數,那么可以使用abs函數進行處理
ABS 函數 返回一個數值的絕對值 |x|
select ABS(-3)返回結果 3
隨機函數
RAND隨機函數
Rand()函數是獲取隨機數的函數,可直接運行select rand() 獲取0~1之間的float型的數字。
如果想要獲取0~100之間的整數隨機數,可以這樣使用
為方便使用,下面延伸了一個方法:
DECLARE @NumBegin Int=60 --隨機數的最小值 DECLARE @NumEnd Int=100 --隨機數的最大值 DECLARE @Decimal Int=2 --保留小數點幾位 SELECT @NumBegin+round((@NumEnd-@NumBegin)*rand(),@Decimal)這個方法通過傳入最大值和最小值以及返回數保留幾位小數,來獲取對應的隨機值。上面這個例子執行結果是獲取60和100之間的隨機數保留兩位小數,如果將2改為-1,則變成獲取60~100之間的10的倍數的整數,不信可以嘗試一下!
其實rand函數有個弊端,獲取的隨機數可能是重復的。這并不是我們想要的結果。
如果換成是newid試試,就不會出現重復。
為什么會出現這樣的結果?
一樣的sql語法,使用newid出來的結果是“真隨機”,而用rand出來的結果卻是“偽隨機”。
而我們需要的是一串純數字,用newid出來的結果并不方便處理。所以,針對這種情景,我們還有一個方式獲得隨機數,那就需要引入另外一個函數 checksum 了,checksum可以和newid結合使用產生隨機數。
Checksum(Newid()獲取隨機數(區別于Rand)
前面有介紹rand獲取隨機數的方法,因為rand本身有一個無法避免的尷尬問題,所以需要引入checksum結合newid的方法來獲取隨機數!
在此之前,先簡單了解一下checksum吧!
Checksum:總和檢驗碼,校驗和。在數據處理和數據通信領域中,用于校驗目的的一組 數據項的和。這些數據項可以是數字或在計算檢驗總和過程中看作數字的其它字符串。它通常是以十六進制為數制表示的形式, 如果校驗和的數值超過十六進制的FF,也就是255. 就要求其補碼作為校驗和.通常用來在通信中,尤其是遠距離通信中保證數據的完整性和準確性。
在SQLServer中Checksum()需要傳入1個參數,可以是任何類型,如下示例:
可以看出,傳入不同參數就有不同的返回值,每個參數的返回值都是固定的,而且還有可能會出現負數的,幾乎看不出有什么規律~
因此,我們可以通過傳入newid()來獲得隨機數,因為newid()每次獲得的值都是唯一的隨機的。
可以以此驗證一下:
返回值即為隨機數。
稍加處理,就可以當作rand來使用了,而且還避免了在某些情景下rand獲得一堆重復的隨機數的尷尬局面:
SELECT CHECKSUM = CONVERT(BIGINT,RIGHT(ABS(CHECKSUM(Newid())),9))*0.1/100000000,RAND=RAND() union all SELECT CHECKSUM = CONVERT(BIGINT,RIGHT(ABS(CHECKSUM(Newid())),9))*0.1/100000000,RAND=RAND() union all SELECT CHECKSUM = CONVERT(BIGINT,RIGHT(ABS(CHECKSUM(Newid())),9))*0.1/100000000,RAND=RAND()可以和Rand放在一起比較,看起來區別不大。
下面有一張臨時表,只有id一個字段,我用checksum和rand兩種方法分別給每個id附上一個隨機數:
看出問題所在了吧!rand獲得的隨機數都是一樣的,而checksum結合newid的方法獲得的隨機數才是我們想要的!
下面延伸一個方法,供將來有需要獲得隨機數的時候使用!新建一個標量值函數,通過傳入參數最大值、最小值、保留幾位小數、以及newid()來獲得隨機數:
Create FUNCTION Scalar_CheckSumNEWID (@From int,@To int,@Keep int,@newid varchar(50) ) RETURNS float BEGINDECLARE @ResultVar floatSELECT @ResultVar=CONVERT(BIGINT,RIGHT(ABS(CHECKSUM(@newid)),9))*0.1/100000000RETURN @From+round((@To-@From)*@ResultVar,@Keep) END GO注:newid之所以要放在傳入參數中,是因為想newid和rand之類的不能放在函數的本身執行,只能通過傳入參數帶入
隨機實例操作
向上取整隨機整數
select cast (floor(rand()*80) AS datetime ) AS 大頭兒子向下取整隨機整數
select CEILING(rand()*100) as 小頭爸爸生成一段范圍內的隨機數字
declare@Result float DECLARE @Upper float DECLARE @Lower float SET @Lower = 50 SET @Upper = 100 SELECT @Result = ROUND(((@Upper - @Lower -1) * RAND() + @Lower), 3) SELECT @Result生成一段時間內的隨機時間
declare @Date_start datetime declare @Date_end datetime set @Date_start= '2021-01-01' set @Date_end=getdate() select 時間=dateadd(minute,abs(checksum(newid()))%(datediff(minute,@Date_start,@Date_end)+1),@Date_start)這里我們引用到另一個時間差值函數
在下一篇筆記里講
總結
以上是生活随笔為你收集整理的SQL中的随机函数-笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一图读懂 | 亿美软通富媒体消息助力营销
- 下一篇: Android 适配器 自定义