I need to check (here for an example) if the average earnings of DE workers are higher than IT workers. I tried using
SELECT IF( (SELECT AVG(earnings) FROM workers WHERE country LIKE 'DE') > (SELECT AVG(earnings) FROM workers WHERE country LIKE 'IT'), 'True', 'False');
but it doesn’t seem to work. Is there any way to do this in PostgresSQL (I am using version 14)
first_name | last_name | country | earnings |
---|---|---|---|
Andrea | Pfeiffer | DE | 800 |
Eufrosina | Marchesi | IT | 2975 |
Elisa | Sabbatini | IT | 2450 |
Marco | Grunewald | DE | 3000 |
Doreen | Kalb | DE | 5000 |
Isidoro | Bruno | IT | 1100 |
Lucas | Mueller | DE | 3000 |
Ausonio | Loggia | IT | 1300 |
Advertisement
Answer
Postgres knows a Boolean type and Boolean expressions will evaluate to a value of that type. So you could simply SELECT
the expression.
SELECT (SELECT avg(earnings) FROM workers WHERE country = 'DE') > (SELECT avg(earnings) FROM workers WHERE country = 'IT');
Or, if you explicitly need strings, use a CASE
expression.
SELECT CASE WHEN (SELECT avg(earnings) FROM workers WHERE country = 'DE') > (SELECT avg(earnings) FROM workers WHERE country = 'IT') THEN 'True' ELSE 'False' END;
And you could even use Postgres’ FILTER
to get rid of the sub selects. (That might be a bit faster.)
For a Boolean:
SELECT avg(earnings) FILTER (WHERE country = 'DE') > avg(earnings) FILTER (WHERE country = 'IT') FROM workers;
For a string:
SELECT CASE WHEN avg(earnings) FILTER (WHERE country = 'DE') > avg(earnings) FILTER (WHERE country = 'IT') THEN 'True' ELSE 'False' END FROM workers;
Instead of FILTER
you could also use a CASE
expression as argument to avg()
with the same effect.
avg(earnings) FILTER (WHERE country = 'DE')
would become
avg(CASE WHEN country = 'DE' THEN earnings END)
(and analog for 'IT'
).
That would also work in many other DBMS, not just Postgres.