我正在尝试编写一个查询,该查询返回任意大小的代表性数据样本。我想通过仅选择第 nth 行来实现此目的,其中 n 使得整个结果集尽可能接近任意大小。
我希望它能够在结果集通常小于任意大小的情况下起作用。在这种情况下,应返回整个结果集。
我找到了this question它展示了如何选择每第 nth 行。
这是我到目前为止所拥有的:
SELECT * FROM (
SELECT *, ((row_number() OVER (ORDER BY "time"))
% ceil(count(*)::FLOAT / 500::FLOAT)::BIGINT) AS rn
FROM data_raw) sa
WHERE sa.rn=0;
这会导致以下错误:
ERROR: column "data_raw.serial" must appear in the GROUP BY clause or be used in an aggregate function Position: 23
像这样删除 n
的计算是有效的:
SELECT * FROM (
SELECT *, (row_number() OVER (ORDER BY "time"))
% 50 AS rn FROM data_raw) sa
LIMIT 500;
我还尝试将计算移至 WHERE 子句:
SELECT * FROM (
SELECT *, (row_number() OVER (ORDER BY "time")) AS rn
FROM data_raw) sa
WHERE (sa.rn % ceil(count(*)::FLOAT / 500::FLOAT)::BIGINT)=0;
这也会导致错误:
ERROR: aggregate functions are not allowed in WHERE Position: 108
有谁对如何修复我的查询或更好的方法有任何想法吗?
我也考虑过使用随机数和概率来选择行,但我宁愿做一些确定性的事情,而不会出现聚集的可能性。
最佳答案
您第一次尝试的错误是您无法将聚合函数 count(*)
与未聚合的行选择混合在一起。您可以通过使用 count()
作为窗口聚合函数来解决此问题:
SELECT * FROM (
SELECT *, ((row_number() OVER (ORDER BY "time"))
% ceil(<b>count(*) OVER ()</b> / 500.0)::int) AS rn
FROM data_raw
) sub
WHERE sub.rn = 0;
详细说明在这里:
@Alexander已修复您上次的尝试。
关于sql - 通过均匀跳过行来选择固定行数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27013286/