如何在全范围内平均减少 SQL 查询的结果行?
Posted
技术标签:
【中文标题】如何在全范围内平均减少 SQL 查询的结果行?【英文标题】:How to reduce result rows of SQL query equally in full range? 【发布时间】:2016-04-29 21:49:50 【问题描述】:我有与日期相关的值。例如,我需要选择 10 年的数据。标准查询结果大约有 3000 行,但我需要在 400px 宽度的图表上显示它们,并通过其余的 api 将它们发送到手机。因此,最好将数据减少到 400 个值。
是否有任何内置方法如何在 SQL Server 或 PostgreSQL 中全面减少数据?我该怎么做?
【问题讨论】:
limit 400
或其他与greatest-n-per-group相关的技术?
where
、group by
等...如何过滤数据取决于您自己,而且不可能有一个完全符合您要求的内置函数。
对于 SQL Server,您可以使用 "SELECT TOP 400 * FROM MyTable" ,我想这取决于您的具体要求。
这个问题真的需要两个rdbms的答案吗?因为确切的答案在 PostgreSQL 和 SQL server 中可能不同
不,一个引擎的提示就足够了。我希望原理是一样的。
【参考方案1】:
在 Postgres 中,width_bucket()
正是您要寻找的东西 - 将基础表中的任意数量的行 (N
) 细化为给定的(最好更小) 数据点数 (n
)。您可以添加对每个数据点有贡献的行数来表示权重。
一个小障碍:我们需要width_bucket()
的变体在double precision
或numeric
数字上运行,而不是timestamp
等。只需提取 epoch 即可使用。
假设这个表定义和当前的 Postgres 版本:
CREATE TABLE tbl (
tbl_id serial PRIMARY KEY
, value numeric NOT NULL
, created_at timestamptz NOT NULL
);
查询:
SELECT width_bucket(extract(epoch FROM t.created_at), x.min_epoch, x.max_epoch, 400) AS pix
, round(avg(t.value), 2) AS avg -- round is optional
, count(*) AS weight
FROM big t
CROSS JOIN (SELECT extract(epoch FROM min(created_at)) AS min_epoch
, extract(epoch FROM max(created_at)) AS max_epoch FROM big) x
GROUP BY 1
ORDER BY 1;
结果:
pix | avg | weight
----+--------+------
1 | 152.58 | 7
2 | 155.16 | 8
3 | 148.89 | 7
...
返回 400 行 - 除非 N
n,在这种情况下您会得到 N
行。
相关:
Multiple averages over evenly spaced intervals Aggregating (x,y) coordinate point clouds in PostgreSQL【讨论】:
以上是关于如何在全范围内平均减少 SQL 查询的结果行?的主要内容,如果未能解决你的问题,请参考以下文章
具有 unnest 的 PostgreSQL 查询不返回空值的结果行
Ms Access SQL:如何防止 Select 查询重复