我正在尝试编写一个返回任意大小的代表性数据样本的查询。我想通过仅选择n th 行来实现这一点,其中n使得整个结果集尽可能接近任意大小。
我希望这在结果集通常小于任意大小的情况下起作用。在这种情况下,应返回整个结果集。
我发现this question显示了如何选择每一个 th 行。
以下是我到目前为止的情况:
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;
这会导致以下错误:
错误:列" data_raw.serial"必须出现在GROUP BY子句中或用于聚合函数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;
这也会导致错误:
错误:WHERE位置:108
中不允许使用聚合函数
有没有人对如何修复我的查询或更好的方法有任何想法?
我还考虑过使用随机数和概率来选择行,但我宁愿做一些确定性的事情而不会有结块的可能性。
答案 0 :(得分:1)
您应该将该计算作为子查询:
WHERE rn % (SELECT CEIL(COUNT(*)::FLOAT / 500:FLOAT)::BIGINT FROM data_raw) = 0
这样,它不再被视为聚合函数,而是作为标量查询。
答案 1 :(得分:1)
您第一次尝试的错误是您无法将聚合函数count(*)
与未聚合选择的行混合使用。您可以使用count()
作为窗口聚合函数来解决此问题:
SELECT * FROM (
SELECT *, ((row_number() OVER (ORDER BY "time"))
% ceil(count(*) OVER () / 500.0)::int) AS rn
FROM data_raw
) sub
WHERE sub.rn = 0;
此处有详细解释:
@Alexander修复了您的上一次尝试。