0

I have a simple log table and want to calculate an error rate per day. The data looks like this:

SELECT count(date(time)) as counts, date(time) as log_date, status 
FROM log 
GROUP BY log_date, status;

returns

 counts |  log_date  |    status
--------+------------+---------------
  38431 | 2016-07-01 | 200 OK
    274 | 2016-07-01 | 404 NOT FOUND
  54811 | 2016-07-02 | 200 OK
    389 | 2016-07-02 | 404 NOT FOUND

but I want something like

 errors |  log_date  | totals 
--------+------------+--------
    274 | 2016-07-01 |  38705
    389 | 2016-07-02 |  45845
    401 | 2016-07-01 |  54378

I've tried using a subquery, but that gives me a running total instead of a daily total, i.e.

SELECT count(*) as errors, date(e.time) as log_date, totals
FROM log e, (SELECT COUNT(*) as totals FROM log t) AS total_counts
WHERE e.status !='200 OK'
GROUP BY log_date, totals
ORDER BY log_date;

returns

 errors |  log_date  | totals
--------+------------+---------
    274 | 2016-07-01 | 1677735
    389 | 2016-07-02 | 1677735
    401 | 2016-07-03 | 1677735

and I get different errors if I try to use a GROUP BY within the subquery. I know I'm close, but I don't know how to make the outer and inner queries both group on the same day.

2
  • Unrelated, but: count(date(time)) is exactly the same thing as count(time). And if time is defined as not null this is exactly the same thing as count(*) Commented Dec 18, 2017 at 7:03
  • Good point, I was confusing myself because I need the date(time) for the GROUP BY. Commented Dec 20, 2017 at 5:52

1 Answer 1

2

Use a case expression inside the aggregate function ("conditional aggregates")

SELECT
       date(time) as log_date
     , count(case when status <> '200 OK' then 1 end) as errors
     , count(*) as totals
FROM log
GROUP BY
       date(time)
Sign up to request clarification or add additional context in comments.

2 Comments

Or use the filter clause: count(*) filter (where status <> '200 OK')
that indeed works. i thought I tried something like that, but it didn't work for me. obviously I did something different. only think to change is you need an as in date(time) log_date. becomes date(time) as log_date. thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.