How to generate a random number with MSSQL

  • Often I need to generate a random number.
  • Microsoft SQL Server provides the RAND() function to generate a random number.
  • The RAND() function only generate the random number at the evaluation time, not the execution.
  • If RAND() is called multiple times within the same stored procedure or select statement or the same transaction, it will return the same number. Not very random.
  • Microsoft provide the NEWID() function that get updated at at every call during execution time.
  • See: Why is the random function not working?

Applies to:

  • Microsoft SQL Server 2005
  • Microsoft SQL Server 2008

NEWID() does NOT work with SQL Server 2000!

Data used

  1. USE sql911;
  2. go
  3. SELECT emp_short,trans_date,debit,credit FROM trans02;
  4. go
emp_short trans_date              debit                 credit
--------- ----------------------- --------------------- ---------------------
000190    2007-06-01 00:00:00.000 NULL                  125.00
000110    2007-06-01 00:00:00.000 NULL                  100.00
000190    2007-06-02 00:00:00.000 25.00                 NULL
000030    2007-07-15 00:00:00.000 357.00                NULL
000030    2007-07-16 00:00:00.000 NULL                  22.00
000030    2007-07-18 00:00:00.000 NULL                  41.00
000030    2007-07-20 00:00:00.000 NULL                  29.50
000110    2007-07-20 00:00:00.000 42.00                 NULL
000110    2007-07-22 00:00:00.000 66.00                 NULL
000110    2007-07-23 00:00:00.000 77.00                 NULL
000010    2007-07-23 00:00:00.000 11.00                 NULL
000010    2007-07-24 00:00:00.000 22.56                 NULL
000010    2007-07-25 00:00:00.000 33.69                 NULL
000070    2007-09-25 00:00:00.000 NULL                  11.11
000070    2007-09-26 00:00:00.000 NULL                  11.22
000070    2007-09-27 00:00:00.000 55.00                 NULL
000070    2007-10-01 00:00:00.000 52.50                 NULL
000160    2007-10-20 00:00:00.000 9.00                  NULL
000160    2007-10-20 01:00:00.000 11.50                 NULL
000160    2007-10-21 00:00:00.000 NULL                  45.00

(20 row(s) affected)

RAND() and random

  1. SELECT RAND() AS 'Fake random number',
  2.        emp_short,trans_date,debit,credit
  3. FROM trans02;
  4. go
Fake random number     emp_short trans_date              debit                 credit
---------------------- --------- ----------------------- --------------------- ---------------------
0.851195969536349      000190    2007-06-01 00:00:00.000 NULL                  125.00
0.851195969536349      000110    2007-06-01 00:00:00.000 NULL                  100.00
0.851195969536349      000190    2007-06-02 00:00:00.000 25.00                 NULL
0.851195969536349      000030    2007-07-15 00:00:00.000 357.00                NULL
0.851195969536349      000030    2007-07-16 00:00:00.000 NULL                  22.00
0.851195969536349      000030    2007-07-18 00:00:00.000 NULL                  41.00
0.851195969536349      000030    2007-07-20 00:00:00.000 NULL                  29.50
0.851195969536349      000110    2007-07-20 00:00:00.000 42.00                 NULL
0.851195969536349      000110    2007-07-22 00:00:00.000 66.00                 NULL
0.851195969536349      000110    2007-07-23 00:00:00.000 77.00                 NULL
0.851195969536349      000010    2007-07-23 00:00:00.000 11.00                 NULL
0.851195969536349      000010    2007-07-24 00:00:00.000 22.56                 NULL
0.851195969536349      000010    2007-07-25 00:00:00.000 33.69                 NULL
0.851195969536349      000070    2007-09-25 00:00:00.000 NULL                  11.11
0.851195969536349      000070    2007-09-26 00:00:00.000 NULL                  11.22
0.851195969536349      000070    2007-09-27 00:00:00.000 55.00                 NULL
0.851195969536349      000070    2007-10-01 00:00:00.000 52.50                 NULL
0.851195969536349      000160    2007-10-20 00:00:00.000 9.00                  NULL
0.851195969536349      000160    2007-10-20 01:00:00.000 11.50                 NULL
0.851195969536349      000160    2007-10-21 00:00:00.000 NULL                  45.00

(20 row(s) affected)
  1. As you can see from this example, the random number is the same for all the rows retrieve.
  2. RAND() did generate a random number: 0.851195969536349, but RAND() is only calculated once at evaluation time.

Real random number

  1. SELECT ABS(CAST(CAST(newid() AS VARBINARY) AS INT)) AS 'Integer random number',
  2.        emp_short,trans_date,debit,credit
  3. FROM trans02;
  4. go
Integer random number emp_short trans_date              debit                 credit
--------------------- --------- ----------------------- --------------------- ---------------------
1452746779            000190    2007-06-01 00:00:00.000 NULL                  125.00
1511506064            000110    2007-06-01 00:00:00.000 NULL                  100.00
1189697883            000190    2007-06-02 00:00:00.000 25.00                 NULL
1767010407            000030    2007-07-15 00:00:00.000 357.00                NULL
1522053383            000030    2007-07-16 00:00:00.000 NULL                  22.00
335397851             000030    2007-07-18 00:00:00.000 NULL                  41.00
913022124             000030    2007-07-20 00:00:00.000 NULL                  29.50
1888662992            000110    2007-07-20 00:00:00.000 42.00                 NULL
2074970679            000110    2007-07-22 00:00:00.000 66.00                 NULL
219143447             000110    2007-07-23 00:00:00.000 77.00                 NULL
1618934769            000010    2007-07-23 00:00:00.000 11.00                 NULL
1355023251            000010    2007-07-24 00:00:00.000 22.56                 NULL
469286489             000010    2007-07-25 00:00:00.000 33.69                 NULL
522573779             000070    2007-09-25 00:00:00.000 NULL                  11.11
1589686790            000070    2007-09-26 00:00:00.000 NULL                  11.22
229719820             000070    2007-09-27 00:00:00.000 55.00                 NULL
1272022157            000070    2007-10-01 00:00:00.000 52.50                 NULL
1266410131            000160    2007-10-20 00:00:00.000 9.00                  NULL
1870771437            000160    2007-10-20 01:00:00.000 11.50                 NULL
945380068             000160    2007-10-21 00:00:00.000 NULL                  45.00

(20 row(s) affected)
  • NEWID() Creates a unique value of type uniqueidentifier.
  • It's an hexadecimal value derived from the MAC address of the network card plus a unique number from the CPU clock.
  • Line 1: abs(cast(cast(newid() as varbinary) as int)) converts the hexadecimal number to an integer.

NEWID conversion to integer

  1. SELECT newid() AS 'Newid',
  2.        CAST(newid() AS VARBINARY) AS 'Binary newid',
  3.        CAST(CAST(newid() AS VARBINARY) AS INT) AS 'Integer newid',
  4.        ABS(CAST(CAST(newid() AS VARBINARY) AS INT)) AS 'Integer random number',
  5.        emp_short,trans_date,debit,credit
  6. FROM trans02;
  7. go
Newid                                Binary newid                                                   Integer newid Integer random number emp_short trans_date              debit                 credit
------------------------------------ -------------------------------------------------------------- ------------- --------------------- --------- ----------------------- --------------------- ---------------------
8D860AC4-BA39-4D12-91CF-F6F20AF9D59E 0xA9310D064DDB664AB67E58D4FA6140AE                             1042029786    734587047             000190    2007-06-01 00:00:00.000 NULL                  125.00
9C4BC55D-3D34-4614-9176-F79A51C6A7F3 0x6DE131C5C73E7A4E95F7F89544553F42                             1198993494    1902315030            000110    2007-06-01 00:00:00.000 NULL                  100.00
52C4156C-5009-470D-839C-E88BE480F6E0 0xCAF7CF433847204F8F8B3588812BE88A                             1032539244    477287890             000190    2007-06-02 00:00:00.000 25.00                 NULL
C16422A8-0A17-4018-8067-D8BBBB6826AF 0xA17900DCB18C7E45AE07F9CDA9DDCBE8                             -1815203699   168370402             000030    2007-07-15 00:00:00.000 357.00                NULL
1978C40D-6EED-4FBB-8BFB-FCA3FCF6C4D5 0x230041D9D1A94C49B9155F11C7284CC1                             -528147515    1390539847            000030    2007-07-16 00:00:00.000 NULL                  22.00
34B5A0E5-C6B6-46A8-9F88-7607A6C8FE46 0x5D049C513A93D949A9882F4D1B94C343                             -500859888    1634272795            000030    2007-07-18 00:00:00.000 NULL                  41.00
5F6F4C86-83BA-4C40-9790-1B31819029C4 0x474433717DC422478E32B85EEADF84FC                             261480181     519147089             000030    2007-07-20 00:00:00.000 NULL                  29.50
8FEE40A0-5236-431C-BE82-5089C1DAC7C1 0x96D21B3504331B449F740CEF31087835                             -387703423    80932913              000110    2007-07-20 00:00:00.000 42.00                 NULL
8ECE248C-6CD7-42DD-A497-2B36BDBBA617 0x2443EE6698126D4CBBE7B4FA050D9F8D                             -256838228    551421988             000110    2007-07-22 00:00:00.000 66.00                 NULL
BE9B4A6F-FFA9-48F3-BC2B-531388AB4C2B 0xC4277A3D4B41364B918EC2039E32BA8C                             1004216926    1922867090            000110    2007-07-23 00:00:00.000 77.00                 NULL
F5AE9A9F-96B2-414E-A449-F64A07CAF32F 0xA4B24C6986581A44AD0173B21C01E7DE                             993491760     1702907948            000010    2007-07-23 00:00:00.000 11.00                 NULL
A4F2C7DF-3CC7-4F8A-A610-31CC451E813C 0x18482C82D9A9DE4384A42C48BEAFD105                             2042188938    48829800              000010    2007-07-24 00:00:00.000 22.56                 NULL
76D68B35-17DE-4524-A622-0EFB356A07B6 0x7E3698704127F047BA659C5214E5434D                             -455822190    414625411             000010    2007-07-25 00:00:00.000 33.69                 NULL
4A8857B5-EFD8-482B-AA9A-F2229A42040A 0xC06B633E384ADD4BA563569EA748A953                             99199592      2109326246            000070    2007-09-25 00:00:00.000 NULL                  11.11
11C0038D-A122-403D-820D-FA7F3D976480 0x051C81641B5B4C42903506D4F9869843                             -1052003717   832391423             000070    2007-09-26 00:00:00.000 NULL                  11.22
1B890742-7CCD-4F63-8F39-2482046C420E 0xB788BB0908998145A64E5413FE56FD37                             -30965911     2085101769            000070    2007-09-27 00:00:00.000 55.00                 NULL
058CDAEE-C0C5-4C6A-BB14-D61D2E33B44A 0x1A5AD767A87D7147A68B7B8BE59842D6                             -578184588    1264117530            000070    2007-10-01 00:00:00.000 52.50                 NULL
0491BD10-9086-4D08-B163-BFE99553A37A 0x1CF0D32DF73A8E4289A0CF68A90172CB                             -1195859560   1411832937            000160    2007-10-20 00:00:00.000 9.00                  NULL
785DE5DA-9694-4E74-8CF3-4F5E2DBCAB63 0x6E11B2B80A6CCD49BCF5A26571CA5336                             321285309     1998516011            000160    2007-10-20 01:00:00.000 11.50                 NULL
0F9230C1-E05D-48A5-B1C2-A55B3674C3A3 0x59A1B5D15A39DC40B42D56C365391D74                             1890845217    503372419             000160    2007-10-21 00:00:00.000 NULL                  45.00

(20 row(s) affected)
  1. Note that each time we call the NEWID function is reevaluated brand new.
  2. Note that the values of line 3: and the values of line 4: do not match! That's because each call to NEWID() generate a brand new random number.