[SQL] 어떻게 SQL에서 임의의 행을 요청하는?
SQL어떻게 SQL에서 임의의 행을 요청하는?
어떻게 임의의 행을 요청할 수 있습니다 (또는 가능한 한 가까이 참으로 임의) 순수 SQL에서?
해결법
-
==============================
1.이 게시물을 참조 : SQL 데이터베이스 테이블에서 임의의 행을 선택 할 수 있습니다. 그것은 MySQL은, PostgreSQL을, 마이크로 소프트 SQL 서버, IBM DB2 및 Oracle (다음은 해당 링크에서 복사)에서이 작업을 수행하는 방법을 통해 진행됩니다
이 게시물을 참조 : SQL 데이터베이스 테이블에서 임의의 행을 선택 할 수 있습니다. 그것은 MySQL은, PostgreSQL을, 마이크로 소프트 SQL 서버, IBM DB2 및 Oracle (다음은 해당 링크에서 복사)에서이 작업을 수행하는 방법을 통해 진행됩니다
MySQL의와 임의의 행을 선택합니다 :
SELECT column FROM table ORDER BY RAND() LIMIT 1
PostgreSQL을 가진 임의의 행을 선택합니다 :
SELECT column FROM table ORDER BY RANDOM() LIMIT 1
마이크로 소프트 SQL 서버와 임의의 행을 선택합니다 :
SELECT TOP 1 column FROM table ORDER BY NEWID()
IBM DB2와 임의의 행을 선택
SELECT column, RAND() as IDX FROM table ORDER BY IDX FETCH FIRST 1 ROWS ONLY
오라클과 임의의 레코드를 선택 :
SELECT column FROM ( SELECT column FROM table ORDER BY dbms_random.value ) WHERE rownum = 1
-
==============================
2.예레미야와 같은 솔루션
예레미야와 같은 솔루션
SELECT * FROM table ORDER BY RAND() LIMIT 1
작동하지만 그들은 순차적 스캔을 필요로하는 모든 테이블 (각 행의 요구와 관련된 임의의 값이 계산 될 수 있기 때문에 - 그래서 작은 일이 결정될 수 있음), 아주 천천히, 심지어 중간 크기의 테이블이 될 수있다. 나의 추천은 일부 인덱스 숫자 컬럼의 종류 (많은 테이블의 주요 키 등이있다)와 같은 다음 쓰기 뭔가를 사용하는 것입니다 :
SELECT * FROM table WHERE num_value >= RAND() * ( SELECT MAX (num_value ) FROM table ) ORDER BY num_value LIMIT 1
num_value 인덱싱 할 경우에 관계없이 테이블 크기의 로그 시간에 작동합니다. 한 가지주의 :이 num_value 동등 범위 0..MAX (num_value)에 분포되어 있다고 가정합니다. 데이터 집합 강력이 가정에서 벗어나면, 당신은 왜곡 된 결과를 (일부 행이 다른 사람보다 더 자주 나타납니다) 받게됩니다.
-
==============================
3.나는 어떻게 효율적이는 모르겠지만, 전에 사용했습니다 :
나는 어떻게 효율적이는 모르겠지만, 전에 사용했습니다 :
SELECT TOP 1 * FROM MyTable ORDER BY newid()
GUID를 꽤 무작위이기 때문에, 순서는 임의의 행을 얻을 것을 의미합니다.
-
==============================
4.
ORDER BY NEWID()
7.4 밀리 초 소요
WHERE num_value >= RAND() * (SELECT MAX(num_value) FROM table)
0.0065 밀리 초 걸립니다!
확실히 후자의 방법으로 이동합니다.
-
==============================
5.당신은 당신이 사용중인 서버 말을하지 않았다. SQL 서버의 이전 버전에서는, 당신은이를 사용할 수 있습니다 :
당신은 당신이 사용중인 서버 말을하지 않았다. SQL 서버의 이전 버전에서는, 당신은이를 사용할 수 있습니다 :
select top 1 * from mytable order by newid()
SQL Server 2005에서는 최대, 당신은 반복의 임의의 샘플을 얻을 TABLESAMPLE 사용할 수 있습니다 :
SELECT FirstName, LastName FROM Contact TABLESAMPLE (1 ROWS) ;
-
==============================
6.SQL Server의
SQL Server의
NEWID () 의지 작업에 의해 / 위해, 그러나 모든 행에 대한 ID를 생성하기 때문에 큰 결과 세트 매우 비싼 다음 종류의 그 것이다.
TABLESAMPLE ()는 성능면에서 좋다, 그러나 당신은 결과의 응집을 (페이지의 모든 행이 반환됩니다) 얻을 것이다.
더 나은 수행하는 진정한 무작위 샘플 들어, 가장 좋은 방법은 임의로 행을 필터링하는 것입니다. 나는 TABLESAMPLE을 사용하여 결과 세트를 제한은 SQL Server 온라인 문서의 다음 코드 샘플을 발견 :
1,000,000 행이 테이블에 대해 실행하면, 여기에 내 결과는 다음과 같습니다
SET STATISTICS TIME ON SET STATISTICS IO ON /* newid() rows returned: 10000 logical reads: 3359 CPU time: 3312 ms elapsed time = 3359 ms */ SELECT TOP 1 PERCENT Number FROM Numbers ORDER BY newid() /* TABLESAMPLE rows returned: 9269 (varies) logical reads: 32 CPU time: 0 ms elapsed time: 5 ms */ SELECT Number FROM Numbers TABLESAMPLE (1 PERCENT) /* Filter rows returned: 9994 (varies) logical reads: 3359 CPU time: 641 ms elapsed time: 627 ms */ SELECT Number FROM Numbers WHERE 0.01 >= CAST(CHECKSUM(NEWID(), Number) & 0x7fffffff AS float) / CAST (0x7fffffff AS int) SET STATISTICS IO OFF SET STATISTICS TIME OFF
당신이 TABLESAMPLE을 사용하여 멀리 얻을 수 있다면, 그것은 당신에게 최상의 성능을 제공 할 것입니다. 그렇지 NEWID () / 필터 방법을 사용한다. 당신은 큰 결과 집합이있는 경우로 NEWID () / 순서는 최후의 수단이어야한다.
-
==============================
7.가능하면 사용 저장된 문은 RND에 모두 인덱스의 비 효율성 ()와 기록 번호 필드를 생성을 방지 할 수 있습니다.
가능하면 사용 저장된 문은 RND에 모두 인덱스의 비 효율성 ()와 기록 번호 필드를 생성을 방지 할 수 있습니다.
PREPARE RandomRecord FROM "SELECT * FROM table LIMIT ?,1"; SET @n=FLOOR(RAND()*(SELECT COUNT(*) FROM table)); EXECUTE RandomRecord USING @n;
-
==============================
8.가장 좋은 방법은 그 목적을 위해 새 열에서 임의의 값을 넣고,이 (pseude 코드 + SQL) 같은 것을 사용하고 있습니다 :
가장 좋은 방법은 그 목적을 위해 새 열에서 임의의 값을 넣고,이 (pseude 코드 + SQL) 같은 것을 사용하고 있습니다 :
randomNo = random() execSql("SELECT TOP 1 * FROM MyTable WHERE MyTable.Randomness > $randomNo")
이는 미디어 위키 코드에 의해 사용되는 솔루션입니다. 물론,이 작은 값에 대한 몇 가지 편견이지만, 그들은 행이 인출 없을 때 제로 주위에 임의의 값을 포장하기에 충분 것을 발견했다.
NEWID () 전체 테이블을 요구할 수 있습니다 솔루션은 각 행은 훨씬 성능이 좋은 것입니다 새 GUID를 할당 할 수 있도록 스캔 할 수 있습니다.
함수가 한번만 평가되므로 랜드 () 용액 (즉 MSSQL 함께) 모두에서 작동하지 않을 수 있으며 모든 행은 동일한 "랜덤"번호가 할당된다.
-
==============================
9.SQL Server 2005 및 2008의 경우, 우리는 (온라인에서) 개별 행의 무작위 표본을 원하는 경우 :
SQL Server 2005 및 2008의 경우, 우리는 (온라인에서) 개별 행의 무작위 표본을 원하는 경우 :
SELECT * FROM Sales.SalesOrderDetail WHERE 0.01 >= CAST(CHECKSUM(NEWID(), SalesOrderID) & 0x7fffffff AS float) / CAST (0x7fffffff AS int)
-
==============================
10.대신이 권장되지 않는, LAND ()를 사용하여, 당신은 단순히 최대 ID (= 최대)를받을 수 있습니다 :
대신이 권장되지 않는, LAND ()를 사용하여, 당신은 단순히 최대 ID (= 최대)를받을 수 있습니다 :
SELECT MAX(ID) FROM TABLE;
1..Max 사이에 임의의를 얻을 수 (= My_Generated_Random)
My_Generated_Random = rand_in_your_programming_lang_function(1..Max);
다음이 SQL을 실행
SELECT ID FROM TABLE WHERE ID >= My_Generated_Random ORDER BY ID LIMIT 1
IDS가 선택한 값과 같거나 높다 모든 행을 검사 않습니다. 그것은 다음과 같이 쿼리를 수정, 테이블 아래 행 사냥하고 My_Generated_Random보다 같거나 낮은 ID를 얻을 수도 있습니다 :
SELECT ID FROM TABLE WHERE ID <= My_Generated_Random ORDER BY ID DESC LIMIT 1
-
==============================
11.@ CNU의 대답에 BillKarwin의 코멘트 @에 지적 ...
@ CNU의 대답에 BillKarwin의 코멘트 @에 지적 ...
한계와 결합 할 때, 나는 그것이 훨씬 더 임의의 순서로하는 대신에 가입하기 (PostgreSQL을 9.1 이상에서) 직접 실제 행을 주문 수행하는 것으로 나타났습니다 : 예를 들어, t AS SELECT * FROM tbl_post 가입 ... 랜드 AS JOIN (SELECT ID, CAST (RANDOM -2147483648 * () 정수 AS) tbl_post FROM WHERE CREATE_TIME> = 1,349,928,000 ) R = ON r.id t.id WHERE CREATE_TIME> = 1,349,928,000 및 ... ORDER BY의 r.rand LIMIT (100)
그냥 'R'이 그것으로 합류하지만 여전히 가능 'R'의 행 수를 제한하는 복잡한 쿼리에서 가능한 모든 키 값에 대한 '랜드'값을 생성 있는지 확인하십시오.
정수로 CAST는 정수 단일 정밀도 부동 유형에 대한 특정 종류의 최적화를 가지고 PostgreSQL의 9.2에 특히 유용합니다.
-
==============================
12.여기에 솔루션의 대부분은 정렬을 피하기 위해 목표로,하지만 그들은 여전히 테이블에 걸쳐 순차적 스캔을 확인해야합니다.
여기에 솔루션의 대부분은 정렬을 피하기 위해 목표로,하지만 그들은 여전히 테이블에 걸쳐 순차적 스캔을 확인해야합니다.
인덱스 스캔로 전환하여 순차 검색을 피할 수있는 방법도 있습니다. 당신이 당신의 임의 행의 인덱스 값을 알고 있다면 당신은 거의 instantially 결과를 얻을 수 있습니다. 문제는 - 인덱스 값을 추측하는 방법.
다음 솔루션은 PostgreSQL의 8.4에서 작동합니다 :
explain analyze select * from cms_refs where rec_id in (select (random()*(select last_value from cms_refs_rec_id_seq))::bigint from generate_series(1,10)) limit 1;
상기 I 액은 범위 0에서 10 개의 다양한 랜덤 지수 값 .. [ID의 마지막 값]을 추측한다.
수 (10)는 임의의 - 그것은 (놀랍게도) 응답 시간에 큰 영향을 미치지 않는 100 또는 1000을 사용할 수 있습니다.
한 가지 문제가있다 - 당신이 놓칠 수있는 스파 스 ID를 가지고있는 경우. 이 솔루션은 백업 계획 : 랜덤 ()의 요청에 의한이 경우에 순수한 오래된 순서를하는 것입니다. 이 같은 ID의 모습을 결합 할 경우 :
explain analyze select * from cms_refs where rec_id in (select (random()*(select last_value from cms_refs_rec_id_seq))::bigint from generate_series(1,10)) union all (select * from cms_refs order by random() limit 1) limit 1;
아니 노조 ALL 절. 이 경우 첫 번째 부분은 두 번째 실행 불필요한 데이터를 반환하는 경우!
-
==============================
13.후반,하지만 그래서 후손을 위해, 내가 대체 솔루션을 추가 할 것입니다, 여기에 Google을 통해 얻었다.
후반,하지만 그래서 후손을 위해, 내가 대체 솔루션을 추가 할 것입니다, 여기에 Google을 통해 얻었다.
또 다른 방법은 주문을 번갈아 두 번 TOP을 사용하는 것입니다. 이 "순수한 SQL은"인 경우는 TOP에서 변수를 사용하기 때문에 나는 모르겠지만, 내가 임의의 단어를 원한다면 여기, 내가 사전에있는 단어의 테이블에 대해 사용 예입니다 SQL 서버 2008에서 작동합니다.
SELECT TOP 1 word FROM ( SELECT TOP(@idx) word FROM dbo.DictionaryAbridged WITH(NOLOCK) ORDER BY word DESC ) AS D ORDER BY word ASC
물론, 한 범위는 포괄적으로, 목표 테이블에서 (*) 계산하는 것이 다소 임의로 생성 @idx 정수이다. 당신의 열이 인덱스되면, 당신도 그 혜택을 얻을 것입니다. 또 다른 장점은 허용되지 않습니다 () NEWID 때문에, 함수에서 사용할 수 있다는 것입니다.
마지막으로, NEWID ()의 간부 시간의 1/10에 대한 위의 쿼리 실행 - 같은 테이블에 쿼리의 유형입니다. YYMV.
-
==============================
14.또한 새로운 ID () 함수를 사용하려고 할 수 있습니다.
또한 새로운 ID () 함수를 사용하려고 할 수 있습니다.
그냥 새로운 ID () 함수에 의해 쿼리 및 사용 순서를 작성합니다. 그것은 매우 무작위.
-
==============================
15.MySQL을위한 임의의 기록을 얻을 수 있습니다
MySQL을위한 임의의 기록을 얻을 수 있습니다
SELECT name FROM random AS r1 JOIN (SELECT (RAND() * (SELECT MAX(id) FROM random)) AS id) AS r2 WHERE r1.id >= r2.id ORDER BY r1.id ASC LIMIT 1
세부 사항은 더 http://jan.kneschke.de/projects/mysql/order-by-rand/
-
==============================
16.확실히 대답이 변화를 아직 보지 못했다. 나는 동일한 행 세트마다 선택, 초기 씨앗 주어, 내가 필요한 추가적인 제약이 있었다.
확실히 대답이 변화를 아직 보지 못했다. 나는 동일한 행 세트마다 선택, 초기 씨앗 주어, 내가 필요한 추가적인 제약이 있었다.
MS SQL의 경우 :
최소 예 :
select top 10 percent * from table_name order by rand(checksum(*))
정규화 실행 시간 : 1.00
변경 () 예 :
select top 10 percent * from table_name order by newid()
정규화 실행 시간 : 1.02
NEWID ()가 하찮게 느린 랜드보다 (체크섬 (*)), 당신은 큰 레코드 세트에 대해 그것을 사용하려는되지 않을 수도 있습니다.
초기 씨앗과 선택 :
declare @seed int set @seed = Year(getdate()) * month(getdate()) /* any other initial seed here */ select top 10 percent * from table_name order by rand(checksum(*) % seed) /* any other math function here */
당신이 씨 주어진 동일한 세트를 선택해야하는 경우이 작동하는 것 같다.
-
==============================
17.MSSQL에서 사용 (11.0.5569 테스트)
MSSQL에서 사용 (11.0.5569 테스트)
SELECT TOP 100 * FROM employee ORDER BY CRYPT_GEN_RANDOM(10)
속도가 매우 빠르고보다
SELECT TOP 100 * FROM employee ORDER BY NEWID()
-
==============================
18.SQL 서버에서 당신은 꽤 좋은 임의성을 얻기 위해 NEWID ()와 TABLESAMPLE을 결합하고 여전히 속도를 가질 수있다. 당신이 정말로 행만의 1 또는 소수를하려는 경우에 특히 유용합니다.
SQL 서버에서 당신은 꽤 좋은 임의성을 얻기 위해 NEWID ()와 TABLESAMPLE을 결합하고 여전히 속도를 가질 수있다. 당신이 정말로 행만의 1 또는 소수를하려는 경우에 특히 유용합니다.
SELECT TOP 1 * FROM [table] TABLESAMPLE (500 ROWS) ORDER BY NEWID()
-
==============================
19.
SELECT * FROM table ORDER BY RAND() LIMIT 1
-
==============================
20.나는 CD-남자와 동의해야합니다 : 사용은 "ORDER BY RAND ()는"작은 테이블 멋지게 일을하거나 당신이 할 때 SELECT 몇 번 것입니다.
나는 CD-남자와 동의해야합니다 : 사용은 "ORDER BY RAND ()는"작은 테이블 멋지게 일을하거나 당신이 할 때 SELECT 몇 번 것입니다.
나는 또한 "num_value> = RAND () * ..."기술을 사용하고 난 정말 무작위 결과를 갖고 싶어 나는 테이블에 특별한 "임의"열이 그 하루 정도 한 번 I 업데이트. (해당 컬럼에 인덱스를 가지고해야합니다 특히 때문에) 그 하나의 UPDATE의 실행은 시간이 좀 걸릴 것입니다,하지만 빠른 모든 행에 대해 선택이 실행될 때마다 임의의 숫자를 만드는 것보다 훨씬입니다.
-
==============================
21.TABLESAMPLE 실제로 행의 무작위 표본을 반환하지 않으므로주의하십시오. 그것은 당신의 행을 구성하는 8킬로바이트 페이지의 무작위 표본을보고 쿼리를 지시합니다. 그런 다음 쿼리는이 페이지에 포함 된 데이터에 대해 실행됩니다. 데이터가이 페이지 (삽입 순서 등)에 분류 될 수있는 방법의 때문에,이 실제로 무작위 표본 수없는 데이터가 발생할 수 있습니다.
TABLESAMPLE 실제로 행의 무작위 표본을 반환하지 않으므로주의하십시오. 그것은 당신의 행을 구성하는 8킬로바이트 페이지의 무작위 표본을보고 쿼리를 지시합니다. 그런 다음 쿼리는이 페이지에 포함 된 데이터에 대해 실행됩니다. 데이터가이 페이지 (삽입 순서 등)에 분류 될 수있는 방법의 때문에,이 실제로 무작위 표본 수없는 데이터가 발생할 수 있습니다.
참조 : http://www.mssqltips.com/tip.asp?tip=1308
TABLESAMPLE이 MSDN 페이지 데이터의 실제 샘플 난수를 생성하는 방법의 예를 포함한다.
http://msdn.microsoft.com/en-us/library/ms189108.aspx
-
==============================
22.아직 주문을 사용하여 나열된 아이디어가 많은 것 같다
아직 주문을 사용하여 나열된 아이디어가 많은 것 같다
임시 테이블을 사용하는 경우, 당신은 (솔루션의 많은 같은 제안) 임의의 인덱스를 할당하고 0과 1 사이의 임의의 수보다 큰 첫 번째를 잡아 할 수 있습니다.
(DB2 용) 예를 들면 :
WITH TEMP AS ( SELECT COMLUMN, RAND() AS IDX FROM TABLE) SELECT COLUMN FROM TABLE WHERE IDX > .5 FETCH FIRST 1 ROW ONLY
-
==============================
23.http://akinas.com/pages/en/blog/mysql_random_row/에서 간단하고 효율적인 방법
http://akinas.com/pages/en/blog/mysql_random_row/에서 간단하고 효율적인 방법
SET @i = (SELECT FLOOR(RAND() * COUNT(*)) FROM table); PREPARE get_stmt FROM 'SELECT * FROM table LIMIT ?, 1'; EXECUTE get_stmt USING @i;
-
==============================
24.이 dbms_random.value에 의한 주문 행에 대한 전체 검사를 필요로하고 큰 테이블에 매우 느린 반면 대신 dbms_random.value를 사용하여 오라클에 대한 더 나은 솔루션이있다.
이 dbms_random.value에 의한 주문 행에 대한 전체 검사를 필요로하고 큰 테이블에 매우 느린 반면 대신 dbms_random.value를 사용하여 오라클에 대한 더 나은 솔루션이있다.
대신 사용 :
SELECT * FROM employee sample(1) WHERE rownum=1
-
==============================
25.파이어 버드의 경우 :
파이어 버드의 경우 :
Select FIRST 1 column from table ORDER BY RAND()
-
==============================
26.SQL Server를 2012+ 당신은이 하나의 임의 행에 대해이 작업을 수행하는 쿼리를 FETCH OFFSET 사용할 수 있습니다
SQL Server를 2012+ 당신은이 하나의 임의 행에 대해이 작업을 수행하는 쿼리를 FETCH OFFSET 사용할 수 있습니다
select * from MyTable ORDER BY id OFFSET n ROW FETCH NEXT 1 ROWS ONLY
ID가 ID 열이고, n은 원하는 로우 여기서 0 - 카운트 () 사이의 난수로서 산출 - 1 표 (0은 결국 최초의 행 오프셋)
당신이 ORDER BY 절에와 작업에 대한 색인을 가지고 같은 테이블 데이터에 구멍이 작동합니다. 그것 또한 임의성을 위해 아주 좋은 - 당신이 자신을 밖으로 전달하지만 다른 방법에서의 niggles가 존재하지 않는 것을 작동한다. 또한 성능은 내가 몇 백만 행에 대해 심각한 성능 테스트를 시도하지 적이 있지만 그것이 잘 유지하는 작은 데이터 세트에 아주 좋은입니다.
-
==============================
27.num_value 연속 값을하지 않은 경우에 GreyPanther의 대답 @ 확장 위의 SQL Server 2005 및하십시오. 우리가 균등하게 데이터 세트를 배포하지 않은 경우와 num_value 숫자 만 고유 식별자가 아닌 경우에 경우에도 작동합니다.
num_value 연속 값을하지 않은 경우에 GreyPanther의 대답 @ 확장 위의 SQL Server 2005 및하십시오. 우리가 균등하게 데이터 세트를 배포하지 않은 경우와 num_value 숫자 만 고유 식별자가 아닌 경우에 경우에도 작동합니다.
WITH CTE_Table (SelRow, num_value) AS ( SELECT ROW_NUMBER() OVER(ORDER BY ID) AS SelRow, num_value FROM table ) SELECT * FROM table Where num_value = ( SELECT TOP 1 num_value FROM CTE_Table WHERE SelRow >= RAND() * (SELECT MAX(SelRow) FROM CTE_Table) )
-
==============================
28.은 SQL에서 임의의 기능을 도울 수 있습니다. 당신은 단지 하나 개의 행을 제한하려는 경우 또한, 단지 결국 그를 추가합니다.
은 SQL에서 임의의 기능을 도울 수 있습니다. 당신은 단지 하나 개의 행을 제한하려는 경우 또한, 단지 결국 그를 추가합니다.
SELECT column FROM table ORDER BY RAND() LIMIT 1
from https://stackoverflow.com/questions/19412/how-to-request-a-random-row-in-sql by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] PostgreSQL의 열 이름은 대소 문자를 구분? (0) | 2020.03.07 |
---|---|
[SQL] T-SQL에서 분할 기능과 동등한? (0) | 2020.03.07 |
[SQL] MySQL은 하나를 제외한 모든 중복 행을 삭제 하시겠습니까? [복제] (0) | 2020.03.06 |
[SQL] MySQL은 어떻게 범위에없는 날짜를 채우기 위해? (0) | 2020.03.06 |
[SQL] 신원 증가는 SQL Server 데이터베이스에 점프 (0) | 2020.03.06 |