데이터베이스 테이블의 임의 레코드(T-SQL)
SQL 서버 테이블에서 임의의 레코드를 검색하는 간단한 방법이 있습니까?
단위 테스트 데이터를 랜덤화하고 싶어서 표에서 랜덤 ID를 선택할 수 있는 간단한 방법을 찾고 있습니다.영어에서는 "테이블에서 id가 가장 낮은 id와 테이블에서 가장 높은 id 사이의 난수인 id를 하나 선택하십시오."가 선택됩니다.
쿼리를 실행하고 null 값을 테스트한 다음 null인 경우 다시 실행하지 않고는 방법을 찾을 수 없습니다.
아이디어?
SQL 서버 테이블에서 임의의 레코드를 검색하는 간단한 방법이 있습니까?
네.
SELECT TOP 1 * FROM table ORDER BY NEWID()
설명.
A NEWID()
각 행에 대해 생성되고 테이블이 해당 행에 따라 정렬됩니다.첫 번째 레코드(즉, "가장 낮은" GUID를 가진 레코드)가 반환됩니다.
메모들
GUID는 버전 4 이후 의사 난수로 생성됩니다.
버전 4 UUID는 실제 임의 또는 의사 임의 번호에서 UUID를 생성하기 위한 것입니다.
알고리즘은 다음과 같습니다.
- clock_seq_hi_and_reserved의 가장 중요한 두 비트(비트 6과 7)를 각각 0과 1로 설정합니다.
- 섹션 4.1.3에서 time_hi_and_version 필드의 최상위 비트 4개(비트 12 ~ 15)를 4비트 버전 번호로 설정합니다.
- 다른 모든 비트를 임의로(또는 의사 임의로) 선택한 값으로 설정합니다.
—UUID(Universally Unique Identifier) URN 네임스페이스 - RFC 4122
대안
SELECT TOP 1 * FROM table ORDER BY RAND()
생각대로 되지 않을 것입니다.RAND()
쿼리당 하나의 값을 반환하므로 모든 행이 동일한 값을 공유합니다.GUID 값은 의사 랜덤이지만, 더 까다로운 응용 프로그램을 위한 더 나은 PRNG가 필요합니다.
일반적인 성능은 시스템에 따라 다르지만 약 1,000,000 행에 대해 10초 미만입니다.인덱스에 도달하는 것은 불가능하므로 성능이 상대적으로 제한됩니다.
더 큰 테이블에서 사용할 수도 있습니다.TABLESAMPLE
전체 테이블을 스캔하지 않도록 합니다.
SELECT TOP 1 *
FROM YourTable
TABLESAMPLE (1000 ROWS)
ORDER BY NEWID()
그ORDER BY NEWID
데이터 페이지에 처음 나타나는 행만 반환하지 않도록 하려면 여전히 필요합니다.
테이블의 크기와 정의에 사용할 숫자를 신중하게 선택해야 하며, 행이 반환되지 않는 경우 재시도 로직을 고려할 수 있습니다.이 배경에 있는 수학과 이 기법이 작은 테이블에 적합하지 않은 이유는 여기에 설명되어 있습니다.
또한 MIN(Id)과 MAX(Id) 사이에서 임의의 ID를 얻은 다음
SELECT TOP 1 * FROM table WHERE Id >= @yourrandomid
그것은 항상 당신에게 한 줄을 줄 것입니다.
대용량 데이터를 선택하는 가장 좋은 방법은 다음과 같습니다.
SELECT * FROM Table1
WHERE (ABS(CAST(
(BINARY_CHECKSUM
(keycol1, NEWID())) as int))
% 100) < 10
출처: MSDN
저는 제가 시도했던 방법들을 개선하기 위해 노력하다가 이 게시물을 보게 되었습니다.오래된 방법인 것은 알지만 이 방법은 나열되어 있지 않습니다.테스트 데이터를 생성하고 적용하는 중입니다. 이는 @st(2문자 상태)로 호출되는 SP에서 "주소"에 대한 방법을 보여줍니다.
Create Table ##TmpAddress (id Int Identity(1,1), street VarChar(50), city VarChar(50), st VarChar(2), zip VarChar(5))
Insert Into ##TmpAddress(street, city, st, zip)
Select street, city, st, zip
From tbl_Address (NOLOCK)
Where st = @st
-- unseeded RAND() will return the same number when called in rapid succession so
-- here, I seed it with a guaranteed different number each time. @@ROWCOUNT is the count from the most recent table operation.
Set @csr = Ceiling(RAND(convert(varbinary, newid())) * @@ROWCOUNT)
Select street, city, st, Right(('00000' + ltrim(zip)),5) As zip
From ##tmpAddress (NOLOCK)
Where id = @csr
개별 행의 랜덤 표본을 원하는 경우 TABLESSAMPLE을 사용하는 대신 행을 랜덤으로 필터링하도록 쿼리를 수정합니다.예를 들어, 다음 쿼리는 NEWID 함수를 사용하여 판매 행의 약 1%를 반환합니다.판매 주문 세부 정보 표:
SELECT * FROM Sales.SalesOrderDetail
WHERE 0.01 >= CAST(CHECKSUM(NEWID(), SalesOrderID) & 0x7fffffff AS float)
/ CAST (0x7fffffff AS int)
판매 주문서ID 열은 NEWID()가 행당 한 번씩 평가하여 행당 샘플링을 달성하도록 CHECKSUM 표현식에 포함됩니다.CAST(CHECKSUM(NEWID()), SalesOrder라는 표현식ID) & 0x7ffffff AS float / CAST (0x7ffffff ASint)는 0과 1 사이의 임의의 float 값으로 평가됩니다."
출처: http://technet.microsoft.com/en-us/library/ms189108(v=sql.105).aspx
이에 대한 자세한 설명은 다음과 같습니다.
이것은 어떻게 작동합니까?WHERE 조항을 나누어 설명해 보겠습니다.
CHECKMS 기능은 목록의 항목에 대한 체크섬을 계산하는 중입니다.SalesOrder의 여부에 대해 논쟁이 가능합니다.NEWID()는 새로운 랜덤 GUID를 반환하는 함수이므로 ID도 필요합니다. 따라서 임의의 숫자에 상수를 곱하면 어떤 경우에도 랜덤이 됩니다.실제로, 판매 주문 제외ID는 아무런 차이가 없는 것 같습니다.만약 당신이 열성적인 통계학자이고 이것을 포함하는 것을 정당화할 수 있다면, 아래의 댓글 섹션을 사용하고 제가 왜 틀렸는지 알려주세요!
CHECKSUM 함수는 VARBINARY를 반환합니다.이진수의 (111111111...)에 해당하는 0x7ffffff로 비트 단위 AND 연산을 수행하면 사실상 0과 1의 임의 문자열을 나타내는 십진수 값이 생성됩니다.계수 0x7ffffff로 나누면 이 소수점 이하의 숫자가 0과 1 사이의 숫자로 효과적으로 정규화됩니다.그런 다음 각 행이 최종 결과 집합에 포함될 가치가 있는지 여부를 결정하기 위해 1/x 임계값(이 경우 0.01)이 사용됩니다. 여기서 x는 표본으로 검색할 데이터의 백분율입니다.
출처: https://www.mssqltips.com/sqlservertip/3157/different-ways-to-get-random-data-for-sql-server-data-sampling
언급URL : https://stackoverflow.com/questions/191342/random-record-from-a-database-table-t-sql
'sourcecode' 카테고리의 다른 글
선택한 항목에 바인딩MVVM의 DataGrid 또는 ListBox 항목 (0) | 2023.05.18 |
---|---|
마스터에서 개발 지점으로 "git pull"하는 방법 (0) | 2023.05.18 |
마이크로소프트입니다.VisualBasic 네임스페이스 "true .NET" 코드? (0) | 2023.05.18 |
UI 텍스트 필드 높이를 설정하는 방법은 무엇입니까? (0) | 2023.05.18 |
"git commit"과 "git push"의 차이점은 무엇입니까? (0) | 2023.05.18 |