mysql SQLite -按兰德排序()

xggvc2p6  于 2023-01-12  发布在  Mysql
关注(0)|答案(5)|浏览(108)

在MySQL中我可以使用兰德()函数,在SQLite 3中有替代方法吗?

o2gm4chl

o2gm4chl1#

SELECT * FROM table ORDER BY RANDOM() LIMIT 1;
hs1rzwqc

hs1rzwqc2#

使用random()

SELECT foo FROM bar
  WHERE id >= (abs(random()) % (SELECT max(id) FROM bar))
  LIMIT 1;

**编辑(通过QOP):**由于SQLite Autoincrement ed列上的文档指出:

只要您从不使用最大ROWID值,也从不删除表中具有最大ROWID的条目,上述常规ROWID选择算法 * 将生成单调递增的唯一ROWID *。如果您删除过行,则在创建新行时可能会重新使用以前删除的行中的ROWID
只有在没有INTEGER PRIMARY KEY AUTOINCREMENT列的情况下才是这样(使用INTEGER PRIMARY KEY列时也能正常工作)。无论如何,这应该更易移植/更可靠:

SELECT foo FROM bar
  WHERE _ROWID_ >= (abs(random()) % (SELECT max(_ROWID_) FROM bar))
LIMIT 1;

ROWID_ROWID_OID都是SQLite内部行ID的别名。

inn6fuwd

inn6fuwd3#

已解决:

SELECT * FROM table ORDER BY RANDOM() LIMIT 1;
um6iljoc

um6iljoc4#

要获得更好的性能,请在SQLite中使用此命令:

SELECT * FROM table WHERE id IN (SELECT id FROM table ORDER BY RANDOM() LIMIT x)

这也适用于MySQL,它运行得更快,因为SQL引擎首先将行的投影字段加载到内存中,然后对它们进行排序,这里我们只加载行的id字段并随机排序,然后我们得到其中的X个,并找到默认索引的这X个id的整行。

cbjzeqam

cbjzeqam5#

目标是获得随机结果(无限滚动),同时能够用SQL对结果分页(LIMIT a,b),这需要一个可预测的结果(伪随机,又名PRNG)。
SIN(id + seed)似乎是RANDOM(seed)的一个很好的替代品。
请考虑这个完全用JS编写的演示,它使用SIN(id + seed)评分模拟ORDER BY子句:

// Inspired by:
// https://www.sqlite.org/forum/forumpost/e2216583a4
// https://stackoverflow.com/a/24511461/7776828

// Simulate N autoincrement stable ids 
// (Avoid rowid which is unstable)
const max = 20;
const a = Array();
for (let id = 0; id < max; ++id) {
  a.push({id});
}
console.log(a);

// Order the results by random
const orderByRandom = ({a, seed}) => {
  // For each result, 
  // Use sin(id + seed) to get a stable random score
  const randomScored = a.map(x => { 
    return { ...x, score: Math.sin(x.id + seed) }
  });
  // Sort by the random score
  randomScored.sort((a,b) => a.score - b.score);
  return randomScored;
}

// Used for generating the seed
const random = () => 1 + Math.floor(Math.random() * Number.MAX_SAFE_INTEGER - 1);

let seed;

seed = random(); // seed #1
console.log(orderByRandom({a, seed})); 
console.log(orderByRandom({a, seed})); // Stable, can paginate

seed = random(); // seed #2
console.log(orderByRandom({a, seed})); // New order because new seed

相关问题