복붙노트

[SQL] 어떻게 SQL에서 임의의 행을 요청하는?

SQL

어떻게 SQL에서 임의의 행을 요청하는?

어떻게 임의의 행을 요청할 수 있습니다 (또는 가능한 한 가까이 참으로 임의) 순수 SQL에서?

해결법

  1. ==============================

    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. ==============================

    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. ==============================

    3.나는 어떻게 효율적이는 모르겠지만, 전에 사용했습니다 :

    나는 어떻게 효율적이는 모르겠지만, 전에 사용했습니다 :

    SELECT TOP 1 * FROM MyTable ORDER BY newid()
    

    GUID를 꽤 무작위이기 때문에, 순서는 임의의 행을 얻을 것을 의미합니다.

  4. ==============================

    4.

    ORDER BY NEWID()
    

    7.4 밀리 초 소요

    WHERE num_value >= RAND() * (SELECT MAX(num_value) FROM table)
    

    0.0065 밀리 초 걸립니다!

    확실히 후자의 방법으로 이동합니다.

  5. ==============================

    5.당신은 당신이 사용중인 서버 말을하지 않았다. SQL 서버의 이전 버전에서는, 당신은이를 사용할 수 있습니다 :

    당신은 당신이 사용중인 서버 말을하지 않았다. SQL 서버의 이전 버전에서는, 당신은이를 사용할 수 있습니다 :

    select top 1 * from mytable order by newid()
    

    SQL Server 2005에서는 최대, 당신은 반복의 임의의 샘플을 얻을 TABLESAMPLE 사용할 수 있습니다 :

    SELECT FirstName, LastName
    FROM Contact 
    TABLESAMPLE (1 ROWS) ;
    
  6. ==============================

    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. ==============================

    7.가능하면 사용 저장된 문은 RND에 모두 인덱스의 비 효율성 ()와 기록 번호 필드를 생성을 방지 할 수 있습니다.

    가능하면 사용 저장된 문은 RND에 모두 인덱스의 비 효율성 ()와 기록 번호 필드를 생성을 방지 할 수 있습니다.

    PREPARE RandomRecord FROM "SELECT * FROM table LIMIT ?,1";
    SET @n=FLOOR(RAND()*(SELECT COUNT(*) FROM table));
    EXECUTE RandomRecord USING @n;
    
  8. ==============================

    8.가장 좋은 방법은 그 목적을 위해 새 열에서 임의의 값을 넣고,이 (pseude 코드 + SQL) 같은 것을 사용하고 있습니다 :

    가장 좋은 방법은 그 목적을 위해 새 열에서 임의의 값을 넣고,이 (pseude 코드 + SQL) 같은 것을 사용하고 있습니다 :

    randomNo = random()
    execSql("SELECT TOP 1 * FROM MyTable WHERE MyTable.Randomness > $randomNo")
    

    이는 미디어 위키 코드에 의해 사용되는 솔루션입니다. 물론,이 작은 값에 대한 몇 가지 편견이지만, 그들은 행이 인출 없을 때 제로 주위에 임의의 값을 포장하기에 충분 것을 발견했다.

    NEWID () 전체 테이블을 요구할 수 있습니다 솔루션은 각 행은 훨씬 성능이 좋은 것입니다 새 GUID를 할당 할 수 있도록 스캔 할 수 있습니다.

    함수가 한번만 평가되므로 랜드 () 용액 (즉 MSSQL 함께) 모두에서 작동하지 않을 수 있으며 모든 행은 동일한 "랜덤"번호가 할당된다.

  9. ==============================

    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. ==============================

    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. ==============================

    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. ==============================

    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. ==============================

    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. ==============================

    14.또한 새로운 ID () 함수를 사용하려고 할 수 있습니다.

    또한 새로운 ID () 함수를 사용하려고 할 수 있습니다.

    그냥 새로운 ID () 함수에 의해 쿼리 및 사용 순서를 작성합니다. 그것은 매우 무작위.

  15. ==============================

    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. ==============================

    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. ==============================

    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. ==============================

    18.SQL 서버에서 당신은 꽤 좋은 임의성을 얻기 위해 NEWID ()와 TABLESAMPLE을 결합하고 여전히 속도를 가질 수있다. 당신이 정말로 행만의 1 또는 소수를하려는 경우에 특히 유용합니다.

    SQL 서버에서 당신은 꽤 좋은 임의성을 얻기 위해 NEWID ()와 TABLESAMPLE을 결합하고 여전히 속도를 가질 수있다. 당신이 정말로 행만의 1 또는 소수를하려는 경우에 특히 유용합니다.

    SELECT TOP 1 * FROM [table] 
    TABLESAMPLE (500 ROWS) 
    ORDER BY NEWID()
    
  19. ==============================

    19.

     SELECT * FROM table ORDER BY RAND() LIMIT 1
    
  20. ==============================

    20.나는 CD-남자와 동의해야합니다 : 사용은 "ORDER BY RAND ()는"작은 테이블 멋지게 일을하거나 당신이 할 때 SELECT 몇 번 것입니다.

    나는 CD-남자와 동의해야합니다 : 사용은 "ORDER BY RAND ()는"작은 테이블 멋지게 일을하거나 당신이 할 때 SELECT 몇 번 것입니다.

    나는 또한 "num_value> = RAND () * ..."기술을 사용하고 난 정말 무작위 결과를 갖고 싶어 나는 테이블에 특별한 "임의"열이 그 하루 정도 한 번 I 업데이트. (해당 컬럼에 인덱스를 가지고해야합니다 특히 때문에) 그 하나의 UPDATE의 실행은 시간이 좀 걸릴 것입니다,하지만 빠른 모든 행에 대해 선택이 실행될 때마다 임의의 숫자를 만드는 것보다 훨씬입니다.

  21. ==============================

    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. ==============================

    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. ==============================

    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. ==============================

    24.이 dbms_random.value에 의한 주문 행에 대한 전체 검사를 필요로하고 큰 테이블에 매우 느린 반면 대신 dbms_random.value를 사용하여 오라클에 대한 더 나은 솔루션이있다.

    이 dbms_random.value에 의한 주문 행에 대한 전체 검사를 필요로하고 큰 테이블에 매우 느린 반면 대신 dbms_random.value를 사용하여 오라클에 대한 더 나은 솔루션이있다.

    대신 사용 :

    SELECT *
    FROM employee sample(1)
    WHERE rownum=1
    
  25. ==============================

    25.파이어 버드의 경우 :

    파이어 버드의 경우 :

    Select FIRST 1 column from table ORDER BY RAND()
    
  26. ==============================

    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. ==============================

    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. ==============================

    28.은 SQL에서 임의의 기능을 도울 수 있습니다. 당신은 단지 하나 개의 행을 제한하려는 경우 또한, 단지 결국 그를 추가합니다.

    은 SQL에서 임의의 기능을 도울 수 있습니다. 당신은 단지 하나 개의 행을 제한하려는 경우 또한, 단지 결국 그를 추가합니다.

    SELECT column FROM table
    ORDER BY RAND()
    LIMIT 1
    
  29. from https://stackoverflow.com/questions/19412/how-to-request-a-random-row-in-sql by cc-by-sa and MIT license