Oracle数据库GROUP BY去重后使用SAMPLE子句报ORA-00933错误如何解决
错误原因
Oracle的SAMPLE子句仅支持直接作用于物理表,无法用于子查询、内联视图等派生结果集,你直接在子查询后面加SAMPLE(5)不符合语法规则,因此抛出ORA-00933错误。
正确实现方案
方案1:全量去重后随机采样(完全匹配需求,推荐)
通过随机函数给去重后的结果排序,再按比例截取行,实现和SAMPLE(5)等价的5%采样效果。
Oracle 12c及以上版本写法:
SELECT * FROM ( SELECT names, min(a) min_a, min(b) min_b FROM 你的表名 GROUP BY names ORDER BY DBMS_RANDOM.VALUE ) FETCH FIRST 5 PERCENT ROWS ONLY;
Oracle 11g及更早版本写法:
SELECT * FROM ( SELECT t.*, ROWNUM rn FROM ( SELECT names, min(a) min_a, min(b) min_b FROM 你的表名 GROUP BY names ORDER BY DBMS_RANDOM.VALUE ) t ) WHERE rn <= (SELECT COUNT(DISTINCT names) * 0.05 FROM 你的表名);
方案2:先采样原表再去重(适合超大数据量场景)
如果你的表数据量极大,全量分组去重成本过高,可以调整逻辑先对原表采样再去重,该方案采样精度略低于方案1,适合对准确性要求不高的场景:
SELECT names, min(a) min_a, min(b) min_b FROM 你的表名 SAMPLE(5) GROUP BY names;
注意:该方案逻辑是先抽取原表5%的行,再对这些行的names去重,和「先全量去重再抽取5%的name」的原始需求逻辑有差异,按需选择。
内容的提问来源于stack exchange,提问作者fero
相关产品推荐
相关产品推荐

