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?
I suppose, what you are actually trying to do should look like this:
While there is an aggregate function in the top
SELECTlist of the subselect, it cannot return "no row". The aggregate functionmin()converts "no row" toNULL, and the simple form below also does the trick.db<>fiddle here
Oldsqlfiddle
Other problems with your query have already been pointed out. But this is the much simpler solution. It returns an
intervalrather than aninteger.Convert to integer
Simplified with input from artaxerxe.
Simple form does the job without check for "no row":
Details about
EXTRACT(epoch FROM INTERVAL)in the manual.Aggregate functions and
NULLIf you had used the aggregate function
count()instead ofsum()as you had initially, the outcome would be different.count()is a special case among standard aggregate functions in that it never returnsNULL. If no value (or row) is found, it returns0instead.The manual on aggregate functions: