我有一个包含客户 ID、日期和整数的 postgres 表。我需要找到日期在去年的每个客户 ID 的前 3 条记录的平均值。我可以使用下面的 SQL 使用单个 ID 来完成此操作(id 是客户 ID,周末是日期,maxattached 是整数)。
需要注意的是:最大值是每月,这意味着我们只查看给定月份的最高值来创建数据集,这就是我们从日期中提取月份的原因。
SELECT
id,
round(avg(max),0)
FROM
(
select
id,
extract(month from weekending) as month,
extract(year from weekending) as year,
max(maxattached) as max
FROM
myTable
WHERE
weekending >= now() - interval '1 year' AND
id=110070 group by id,month,year
ORDER BY
max desc limit 3
) AS t
GROUP BY id;
如何扩展此查询以包含所有 ID 以及每个 ID 的单个平均数?
这里是一些示例数据:
ID | MaxAttached | Weekending
110070 | 5 | 2011-11-10
110070 | 6 | 2011-11-17
110071 | 4 | 2011-11-10
110071 | 7 | 2011-11-17
110070 | 3 | 2011-12-01
110071 | 8 | 2011-12-01
110070 | 5 | 2012-01-01
110071 | 9 | 2012-01-01
因此,对于这个示例表,我希望收到以下结果:
ID | MaxAttached
110070 | 5
110071 | 8
这对每个 ID 指定月份的最高值进行平均(110070 为 6,3,5,110071 为 7,8,9)
注意:postgres 版本 8.1.15
最佳答案
首先 - 获取每个客户和月份的max(maxattached)
:
SELECT id,
max(maxattached) as max_att
FROM myTable
WHERE weekending >= now() - interval '1 year'
GROUP BY id, date_trunc('month',weekending);
下一步 - 对于每个客户,对他的所有值(value)观进行排名:
SELECT id,
max_att,
row_number() OVER (PARTITION BY id ORDER BY max_att DESC) as max_att_rank
FROM <previous select here>;
下一步 - 为每个客户获取前 3 名:
SELECT id,
max_att
FROM <previous select here>
WHERE max_att_rank <= 3;
下一步 - 获取每个客户的平均值
值:
SELECT id,
avg(max_att) as avg_att
FROM <previous select here>
GROUP BY id;
下一步 - 只需将所有查询放在一起,然后根据您的情况重写/简化它们。
更新:这是一个包含您的测试数据和查询的 SQLFiddle:SQLFiddle .
UPDATE2:这是查询,将在 8.1 上运行:
SELECT customer_id,
(SELECT round(avg(max_att),0)
FROM (SELECT max(maxattached) as max_att
FROM table1
WHERE weekending >= now() - interval '2 year'
AND id = ct.customer_id
GROUP BY date_trunc('month',weekending)
ORDER BY max_att DESC
LIMIT 3) sub
) as avg_att
FROM customer_table ct;
想法 - 获取初始查询并为每个客户运行它(customer_table
- 包含客户所有唯一 id
的表)。
这是包含此查询的 SQLFiddle:SQLFiddle .
仅在版本 8.3 上进行测试(8.1 太旧,无法在 SQLFiddle 上运行)。
关于sql - 需要在 SQL 中找到按 ID 分组的前 3 条记录的平均值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14296002/