ORDER BY random() with seed in SQLITE

前端 未结 4 856
别跟我提以往
别跟我提以往 2020-12-11 00:19

I would like to implement paging for a random set

Select * from Animals ORDER BY random(SEED) LIMIT 100 OFFSET 50  

I tried to set int to

4条回答
  •  醉话见心
    2020-12-11 01:00

    Short answer:

    You can't. SQLite's random() function does not support a seed value.

    Not so short answer:

    Checking SQLite's func.c shows that random() is defined without any parameters..

    VFUNCTION(random,            0, 0, 0, randomFunc       ),
    

    ..and this randomFunc() just calls sqlite3_randomness() (again without any explicit seed value) to obtain a random value of sizeof(sqlite_int64) bytes.

    Internally, the implementation of sqlite3_randomness() (see random.c) will set up the RC4 pseudo-random number generator the first time it is used with random seed values obtained from the OS:

      /* Initialize the state of the random number generator once,
      ** the first time this routine is called.  The seed value does
      ** not need to contain a lot of randomness since we are not
      ** trying to do secure encryption or anything like that...
      **
      ** [..]
      */
      if( !wsdPrng.isInit ){
          [..]
          sqlite3OsRandomness(sqlite3_vfs_find(0), 256, k);
          [..]
          wsdPrng.isInit = 1;
      }
    

    Actually, SQLite's unit test functions themselves just use memcpy() on the global sqlite3Prng struct to save or restore the state of the PRNG during test runs.

    So, unless you're willing to do something weird (like create a temporary table of consecutive numbers (1..max(Animals)), shuffle those around and use them to select 'random-seeded' RowIds from your Animals table) I suppose you're out of luck.

提交回复
热议问题