PostgreSQL如何获得某些行的平均值

时间:2018-05-30 14:48:25

标签: sql postgresql

如果标题不是很贴切我道歉,但是我在制定一个简洁的标题时遇到了一些麻烦。无论如何,我有一个表,记录一个人所处的状态。它看起来像:

id, login, state, duration, started_at
1, pdiddy, working, 1200, 2018-05-25 08:30:00
2, pdiddy, lunch, 120, 2018-05-25 9:00:00
3, pdiddy, on_call, 65, 2018-05-25 12:30:00
4, pdiddy, available, 1115, 2018-05-25 12:30:00
5, pdiddy, working, 143, 2018-05-25 12:30:00
6, pdiddy, break1, 150, 2018-05-25 12:30:00
7, pdiddy, working, 2400, 2018-05-25 12:30:00
8, pdiddy, break2, 110, 2018-05-25 12:30:00

我需要为每个用户逐日获得与劳动相关的持续时间的平均值。所以基本上我需要为任何给定日期的“午餐”,“休息1”和“休息2”之外的所有内容加上持续时间,并得到它的平均值。

我尝试这样做,但问题是它在平均之前不会累计与人工相关的日志。我无法弄清楚如何做到这一点。

SELECT
    log.login,
    AVG(log.duration) FILTER (WHERE log.state NOT IN ('lunch', 'break1', 'break2')) AS "labor_average"
FROM
    log
GROUP BY 1

显然我不希望有人为我这样做。我只需指向正确的方向。我显然离解决方案很远,所以我只需要朝着正确的方向努力。非常感谢你提前!

2 个答案:

答案 0 :(得分:0)

首先计算每次登录和每天的总和。

然后计算每次登录的平均值。

SELECT
    login, AVG(SumDuration) AS AvgDuration
FROM
    (
    SELECT
        login, started_at::date, SUM(duration) AS SumDuration
    FROM log
    WHERE log.state NOT IN ('lunch', 'break1', 'break2')
    GROUP BY login, started_at::date
    ) AS T
GROUP BY login;

答案 1 :(得分:0)

我想你希望总和除以天数:

SELECT l.login,
       (SUM(l.duration) FILTER (WHERE l.state NOT IN ('lunch', 'break1', 'break2')) /
        COUNT(DISTINCT date_trunc('day', l.started_at)
       ) AS labor_average
FROM log l
GROUP BY l.login