sql - 通过均匀跳过行来选择固定行数

标签 sql postgresql window-functions postgresql-9.4

我正在尝试编写一个查询,该查询返回任意大小的代表性数据样本。我想通过仅选择第 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/

相关文章:

php - 在一列中显示多行 Mysql 和 PHP

mysql - 如何对 MySQL 慢速查询进行故障排除/调试?

sql - 在哪里可以找到预定义 Oracle pl/SQL 异常的完整列表?

SQL 学校作业,编写一个返回的 SELECT

sql - PostgreSQL 中的窗口函数

c# - SQL查询选择谜题

postgresql - 如果没有数据,使用限制非常慢

sql - 将列的数据类型更改为串行

postgresql - 通过向现有键值加 1 来更新 PostgreSQL JSONB 键值

sql - 窗口函数字段的别名在 HAVING 和 WHERE 子句中使用时导致 "not found"错误