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

  • Post author:
  • Post category:
  • Post last modified:February 8, 2020

공지. 이 글은 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()))을 쓰면 된다.

Author Details
Kubernetes, DevSecOps, AWS, 클라우드 보안, 클라우드 비용관리, SaaS 의 활용과 내재화 등 소프트웨어 개발 전반에 도움이 필요하다면 도움을 요청하세요. 지인이라면 가볍게 도와드리겠습니다. 전문적인 도움이 필요하다면 저의 현업에 방해가 되지 않는 선에서 협의가능합니다.
0 0 votes
Article Rating
5 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
방준영
15 years ago

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

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

최재훈
15 years ago

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

방준영
15 years ago

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

최재훈
15 years ago

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

trackback
2024 years ago

ORDER BY NEWID에 대해

Wikipedia에서 발췌 번역 보통 GUID는 마이크로소프트가 구현한 Universally Unique Identifier (UUID) 표준을 일컫는다. 하지만 오라클 데이터베이스, MySQL, dBase 같은 다수의 시스템도 GUID란 용어를 쓴다. 기본 구조 GUID는 16바이트(128비트) 짜리 숫자다. 주로 사용하는 데이터 타입의 구조는 다음과 같다. Bits Bytes Description 32 4 Data1 16 2 Data2 16 2 Data3 64 8 Data4 알고리즘 V1 GUID는 MAC 주소와 시간이 포함되는데……