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.
db<>fiddle here
Oldsqlfiddle
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, and array_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.