MSSQL에서 랜덤 레코드를 얻는 방법

공지. 이 글은 How to get a really random number with MSSQL을 번역한 것입니다.

  • rand()란 무작위 함수는 0과 1을 포함하여 0과 1 사이의 float 값을 반환한다.

  • 온라인 설명서에 따르면 "동일한 초기값으로 RAND()를 반복 호출하면 동일한 결과를 반환한다”라는 문제가 있다. 헉!

  • 온라인 설명서에 따르면 이렇단다. [강조는 내가 한 것이다]

    seed를 지정하지 않으면 Microsoft SQL Server 2005 데이터베이스 엔진은 임의로 초기값을 할당합니다. 지정된 초기값에 대해 반환된 결과는 항상 동일합니다.

적용 대상

  • Microsoft SQL Server 2000
  • Microsoft SQL Server 2005
  • Microsoft SQL Server 2008

테스트 시 사용한 데이터

USE sql911;
go

SELECT counter,emp_short,trans_date,debit,credit
FROM trans02
WHERE counter IS not null;
go
counter     emp_short trans_date              debit                 credit
----------- --------- ----------------------- --------------------- ---------------------
10          000190    2007-06-01 00:00:00.000 NULL                  125.00
20          000110    2007-06-01 00:00:00.000 NULL                  100.00
30          000190    2007-06-02 00:00:00.000 25.00                 NULL
40          000030    2007-07-15 00:00:00.000 357.00                NULL
50          000030    2007-07-16 00:00:00.000 NULL                  22.00
60          000030    2007-07-18 00:00:00.000 NULL                  41.00
70          000030    2007-07-20 00:00:00.000 NULL                  29.50
80          000110    2007-07-20 00:00:00.000 42.00                 NULL
90          000110    2007-07-22 00:00:00.000 66.00                 NULL
100         000110    2007-07-23 00:00:00.000 77.00                 NULL
110         000010    2007-07-23 00:00:00.000 11.00                 NULL
120         000010    2007-07-24 00:00:00.000 22.56                 NULL
130         000010    2007-07-25 00:00:00.000 33.69                 NULL

(13 row(s) affected)

무작위 숫자

SELECT newid() AS 'New id',
	RAND() AS 'Random not working',
	CHECKSUM(newid()) AS 'Checksum',
	counter,emp_short,trans_date,debit,credit
FROM trans02
WHERE counter IS not null
ORDER BY 3;
New id                               Random not working     Checksum    counter     emp_short
------------------------------------ ---------------------- ----------- ----------- ---------
F137931B-664F-4CB7-B597-03105FD9E96A 0.838972959717442      -1608727751 20          000110
3A934F70-5046-4D3D-9F7C-797EAB13B913 0.838972959717442      -1344834565 120         000010
41E3CB22-A949-4908-8BC2-B41B5B5BF577 0.838972959717442      -1134949697 100         000110
45BCFA1F-BD8F-4592-99D6-B78F306A7504 0.838972959717442      -774042085  60          000030
4A976789-B334-4955-A70F-0D85D9C4B2D6 0.838972959717442      -251363326  90          000110
E5AC2F6A-2C8E-4143-B3B9-A21E8B9D4E7C 0.838972959717442      -247038803  130         000010
0F58C42C-7C60-4099-A172-D5C88259AE3D 0.838972959717442      277019267   80          000110
5F88145E-A98C-43E0-BF45-100CBFC736AF 0.838972959717442      389707540   30          000190
F65079CC-7EA0-414E-823B-656E0ED5332B 0.838972959717442      477599931   110         000010
E6C128E8-B547-4D31-BD13-BE90C77604A6 0.838972959717442      876100622   70          000030
7490BBA7-2F6D-4E8E-A399-E1369B38F265 0.838972959717442      1578680847  10          000190
65D886A7-5837-4660-AE25-8AABA9DB1975 0.838972959717442      1693370092  40          000030
A992E547-E740-443C-85C0-679AB2E2A34B 0.838972959717442      2061729487  50          000030

(13 row(s) affected)

NEWID()

  • NEWID()는 진정으로 유일한 16바이트 바이너리 값을 제공한다. 거의 무작위에 가깝다.

  • NEWID()는 16바이트 바이너리 값이다. 이 값은 유일하며 세상 어느 컴퓨터도 똑같은 값을 만들지 않는다.

  • NEWID()는 서버의 네트워크 카드의 MAC 주소 + 애플리케이션 또는 쿼리를 돌리는 컴퓨터의 시계로부터 얻은 유일한 값의 조합이다.

  • NEWID()는 유일한 값을 얻고자 할 때 매우 유용하다.

  • 알파벳과 숫자로 이뤄진 문자열이 아닌 숫자를 셀 때 쓰는 정수가 필요하다면, checksum(newid())abs(checksum(newid()))을 쓰면 된다.

최 재훈

블로그, 페이스북, 트위터 고성능 서버 엔진, 데이터베이스, 지속적인 통합 등 다양한 주제에 관심이 많다.

This Post Has 5 Comments

  1. “…16비트 바이너리…” -> 128비트가 맞겠죠. grin

    그런데 제목에 약간 어폐가 있네요. NEWID()로부터 얻은 GUID 값은 예측가능한 수 여러 개를 조합한 것이기 때문에 랜덤값이 아닙니다(무작위 != 유일). 왜 GUID를 랜덤 키로 쓰면 안되는지는 http://en.wikipedia.org/wiki/Guid 에 나와 있습니다.

  2. 별로 생각 안 하고 원문을 그대로 옮겨서 조사를 해보고 답변해야겠네요. 흠……

  3. 원문을 봤더니 저자가 착각을 해서 “16 byte”라고 써야 할  부분에 “16 bit”라고 써놨네요. 그 아랫줄에서는 “16-byte”라고 제대로 되어 있습니다.

  4. 우선 16바이트로 고쳐놨습니다. 그리고 이 랜덤 이야기는 조금 더 다룰 생각인데 집 컴퓨터엔 개발 도구가 많지 않아 힘들고 내일 일찍 출근해서 실험을 해봐야 알겠네요. ^^

Comments are closed.

Close Menu