Oracle SQL如何选取bar列值唯一的随机10行全列数据?
解决Oracle中选取指定列唯一的随机10条记录问题
嗨,我来帮你搞定这个查询需求~首先得先说说你原来的语句为啥跑不通:HAVING DISTINCT bar的用法是错的,HAVING是配合GROUP BY用来过滤分组结果的,不能直接跟DISTINCT;而且ROWNUM的位置也不对,它是在结果集生成后就立刻生效,原语句的逻辑完全达不到你要的“取bar列唯一的10条随机数据”的效果。
针对你的需求——从foo表中选取bar(对应示例里的item列)值唯一的10条随机数据的所有列,这里有两种靠谱的实现方式:
方法一:先为每个唯一bar选随机记录,再取前10条
这种方式适合先确保每个bar只出一次,再从中选前10个:
SELECT * FROM ( SELECT foo.*, -- 按bar分区,随机排序后给每条记录标序号 ROW_NUMBER() OVER (PARTITION BY bar ORDER BY DBMS_RANDOM.VALUE) AS rn FROM foo ) WHERE rn = 1 -- 只取每个bar对应的第一条随机记录 AND ROWNUM <= 10; -- 限制最终结果为10条
逻辑说明:
- 内层查询用
ROW_NUMBER()窗口函数,以bar为分区键,每个分区内用DBMS_RANDOM.VALUE生成随机值来排序,这样每个bar下的记录会被随机分配序号。 - 外层筛选
rn=1,就得到每个bar对应的一条随机记录。 - 最后用
ROWNUM <=10拿到前10个不同bar的记录。
方法二:先随机选10个唯一bar,再取对应随机记录
如果你的表数据量很大,这种方式效率更高——先缩小范围到10个随机的bar,再取每个bar的随机记录:
SELECT foo.* FROM foo JOIN ( -- 先随机选出10个不同的bar SELECT DISTINCT bar FROM foo ORDER BY DBMS_RANDOM.VALUE FETCH FIRST 10 ROWS ONLY -- Oracle 12c+支持的语法,取前10条 ) random_bars ON foo.bar = random_bars.bar WHERE ROW_NUMBER() OVER (PARTITION BY foo.bar ORDER BY DBMS_RANDOM.VALUE) = 1;
逻辑说明:
- 子查询先从
foo表中随机选出10个不同的bar值。 - 通过JOIN关联原表,只保留这10个bar对应的记录。
- 再用窗口函数为每个bar选一条随机记录,确保最终结果里每个bar只出现一次。
结合你给出的示例数据(只有a、b、c三个item),运行上面的语句会得到这三个item各自的一条随机rate记录;如果表中有更多item,就会随机选出10个不同的item,每个对应一条随机记录。
内容的提问来源于stack exchange,提问作者Tuomas Toivonen
相关产品推荐
相关产品推荐

