【问题标题】:How to reduce result rows of SQL query equally in full range?如何在全范围内平均减少 SQL 查询的结果行?
【发布时间】:2016-04-29 21:49:50
【问题描述】:

我有与日期相关的值。例如,我需要选择 10 年的数据。标准查询结果大约有 3000 行,但我需要在 400px 宽度的图表上显示它们,并通过其余的 api 将它们发送到手机。因此,最好将数据减少到 400 个值。

是否有任何内置方法如何在 SQL Server 或 PostgreSQL 中全面减少数据?我该怎么做?

【问题讨论】:

  • limit 400 或其他与greatest-n-per-group相关的技术?
  • wheregroup by 等...如何过滤数据取决于您自己,而且不可能有一个完全符合您要求的内置函数。
  • 对于 SQL Server,您可以使用 "SELECT TOP 400 * FROM MyTable" ,我想这取决于您的具体要求。
  • 这个问题真的需要两个rdbms的答案吗?因为确切的答案在 PostgreSQL 和 SQL server 中可能不同
  • 不,一个引擎的提示就足够了。我希望原理是一样的。

标签: sql sql-server postgresql


【解决方案1】:

Postgres 中,width_bucket() 正是您要寻找的东西 - 将基础表中的任意数量的行 (N) 细化为给定的(最好更小) 数据点数 (n)。您可以添加对每个数据点有贡献的行数来表示权重。

一个小障碍:我们需要width_bucket() 的变体在double precisionnumeric 数字上运行,而不是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 行。

相关:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-03
    • 1970-01-01
    • 2011-05-09
    • 1970-01-01
    相关资源
    最近更新 更多