SQLite如何实现同组聚合显示且组间随机排序?
实现同字母聚合且字母组随机排序的SQL方案
这个需求的核心是给每个不同的字母分配一个唯一的随机排序值,让同一字母的所有记录共享这个值,这样排序时同字母的记录会聚合在一起,而字母组的顺序会随随机值变化。下面分主流数据库给出具体实现:
核心思路
- 先从原表中提取所有不同的字母,为每个字母生成一个随机值
- 将原表与这个带随机值的字母列表关联,让每条记录都带上对应字母的随机值
- 先按随机值排序(决定字母组的顺序),再按字母排序(保证同字母记录聚合,可选,若不需要同字母内部固定顺序可省略)
各数据库具体实现
MySQL
SELECT t.Letter FROM your_table t JOIN ( -- 给每个不同字母生成唯一随机值 SELECT Letter, RAND() AS rand_val FROM (SELECT DISTINCT Letter FROM your_table) AS distinct_letters ) AS r ON t.Letter = r.Letter ORDER BY r.rand_val, t.Letter;
或者更简洁的写法(利用子查询匹配字母生成随机值):
SELECT Letter FROM your_table ORDER BY (SELECT RAND() FROM (SELECT DISTINCT Letter FROM your_table) l WHERE l.Letter = your_table.Letter), Letter;
PostgreSQL
把MySQL中的RAND()换成PostgreSQL的RANDOM()即可:
SELECT t.Letter FROM your_table t JOIN ( SELECT Letter, RANDOM() AS rand_val FROM (SELECT DISTINCT Letter FROM your_table) AS distinct_letters ) AS r ON t.Letter = r.Letter ORDER BY r.rand_val, t.Letter;
SQL Server
可以用NEWID()生成唯一随机标识符来排序:
SELECT t.Letter FROM your_table t JOIN ( SELECT Letter, NEWID() AS rand_val FROM (SELECT DISTINCT Letter FROM your_table) AS distinct_letters ) AS r ON t.Letter = r.Letter ORDER BY r.rand_val, t.Letter;
也可以用CHECKSUM结合RAND的写法:
SELECT Letter FROM your_table ORDER BY RAND(CHECKSUM(Letter)), Letter;
Oracle
使用DBMS_RANDOM.VALUE生成随机值:
SELECT t.Letter FROM your_table t JOIN ( SELECT Letter, DBMS_RANDOM.VALUE AS rand_val FROM (SELECT DISTINCT Letter FROM your_table) distinct_letters ) r ON t.Letter = r.Letter ORDER BY r.rand_val, t.Letter;
注意事项
- 不要直接用
ORDER BY RAND(), Letter(或对应数据库的随机函数),因为这样每条记录都会生成独立的随机值,会导致同字母的记录被打乱,无法聚合。 - 如果不需要同字母内部的固定顺序,可以去掉
ORDER BY中的t.Letter,只保留随机值排序即可。
内容的提问来源于stack exchange,提问作者Matheus Valin
相关产品推荐
相关产品推荐

