Here is my SQL query:
SELECT (CASE (elapsed_time_from_first_login IS NULL) WHEN true THEN 0 ELSE elapsed_time_from_first_login END) FROM ( SELECT (now()::ABSTIME::INT4 - min(AcctStartTime)::ABSTIME::INT4) FROM radacct WHERE UserName = 'test156') AS elapsed_time_from_first_login;
When I execute the above query, I get this error:
ERROR: CASE types record and integer cannot be matched
From the error message I understand that PostgreSQL
take the second select, respectively elapsed_time_from_first_login
as a row, even if it will always be a single value (because of the min() function).
Question: do you have some suggestions on how to deal with this query?
Advertisement
Answer
I suppose, what you are actually trying to do should look like this:
SELECT COALESCE((SELECT now() - min(acct_start_time) FROM radacct WHERE user_name = 'test156') , interval '0s')
While there is an aggregate function in the top SELECT
list of the subselect, it cannot return “no row”. The aggregate function min()
converts “no row” to NULL
, and the simple form below also does the trick.
Other problems with your query have already been pointed out. But this is the much simpler solution. It returns an interval
rather than an integer
.
Convert to integer
Simplified with input from artaxerxe.
Simple form does the job without check for “no row”:
SELECT COALESCE(EXTRACT(epoch FROM now() - min(acct_start_time))::int, 0) FROM radacct WHERE user_name = 'test156';
Details about EXTRACT(epoch FROM INTERVAL)
in the manual.
Aggregate functions and NULL
If you had used the aggregate function count()
instead of sum()
as you had initially, the outcome would be different. count()
is a special case among standard aggregate functions in that it never returns NULL
. If no value (or row) is found, it returns 0
instead.
The manual on aggregate functions:
It should be noted that except for
count
, these functions return a null value when no rows are selected. In particular,sum
of no rows returns null, not zero as one might expect, andarray_agg
returns null rather than an empty array when there are no input rows. The coalesce function can be used to substitute zero or an empty array for null when necessary.