我有一个查询(postgresql),我想限制用于计算平均值的行
SELECT username,avg(income),count(*) FROM
Events
WHERE to_timestamp(eventtimestamp) >= '2008-02-23' AND
to_timestamp(eventtimestamp) <= '2009-01-03' and username='Joe'
GROUP BY userid
Joe有40个条目,但我想限制用于计算其收入平均值的行数。我知道我可以在查询结尾处添加的限制功能,但这会限制整个查询的输出,而不是<查询头部中的strong> average 命令。有什么提示我怎么能告诉avg只使用前n行?
e.g。 无法正常工作
SELECT username,avg(income) limit 5,count(*) FROM
Events
WHERE to_timestamp(eventtimestamp) >= '2008-02-23' AND
to_timestamp(eventtimestamp) <= '2009-01-03' and username='Joe'
GROUP BY userid
仅在前5行中平均。
谢谢!
答案 0 :(得分:3)
我正在添加答案有两个原因。首先,大多数其他答案会影响count(*)
以及avg()
,这不是问题的一部分。其次,您可能希望为多个用户执行此操作。
所以,您可以尝试以下方法:
SELECT username, avg(case when seqnum <= 40 then income end), count(*)
FROM (select e.*, ROW_NUMBER() over (partition by username order by eventtimestamp desc) as seqnum
from Events e
WHERE to_timestamp(eventtimestamp) >= '2008-02-23' AND
to_timestamp(eventtimestamp) <= '2009-01-03'
) e
GROUP BY username
答案 1 :(得分:2)
您可以采用内部查询的平均值:
SELECT username,avg(income),count(*)
FROM (
SELECT username, income
FROM Events
WHERE to_timestamp(eventtimestamp) BETWEEN '2008-02-23' AND '2009-01-03'
and username='Joe'
LIMIT 5) x
GROUP BY userid;
另请注意使用BETWEEN
答案 2 :(得分:1)
您可以在子选择中使用限制;
SELECT username,avg(income),count(*) FROM
(SELECT * FROM Events
WHERE to_timestamp(eventtimestamp) >= '2008-02-23' AND
to_timestamp(eventtimestamp) <= '2009-01-03' and username='Joe'
order by to_timestamp(eventtimestamp) desc
LIMIT 10) sub
GROUP BY userid;
答案 3 :(得分:1)
如果你偶然喜欢(或者不关心)5行的平均值,那么你可以使用窗函数来避免使用子选项:
select
username,
avg(income) over(rows 4 preceding),
count(*)
from events
where to_timestamp(eventtimestamp) >= '2008-02-23' and
to_timestamp(eventtimestamp) <= '2009-01-03' and username='joe'
group by userid
如果我理解你的评论,你确实可以使用count
作为窗口函数:
count(*) over(rows 4 preceding)
或者如果不想计算空值:
count(income) over(rows 4 preceding)
答案 4 :(得分:0)
已发布好的答案。我建议使用Unix纪元进行比较和排序如下:
SELECT userid, username, avg(income), count(*)
FROM (
SELECT userid, username, income
FROM Events
WHERE eventtimestamp BETWEEN date_part('epoch', '2008-02-23'::date)
AND date_part('epoch', '2009-01-03'::date)
AND username='Joe'
ORDER BY eventtimestamp DESC LIMIT 10) AS q
GROUP BY userid, username;
通过这样做,我没有为每一行调用转换函数。另一种方法可能是在to_timestamp(eventtimestamp)
上创建一个功能索引,但我认为我这样做的方式更有效。
请注意,我已经包含了userid和username - 原始示例会抛出错误,因为username不在'GROUP BY'子句中。
除此之外,如果您想从随机样本而不是最后的 n 条目进行计算,您可以将排序更改为ORDER BY random()