1

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

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

6 Comments

Thank you. I didn't think it could be written down so simply. The second expression is exactly what I needed. As I understand it FILTER is used only in PostgreSQL so I can't use it in MySQL for example?
@DominikCzekański: Yes, FILTER is a Postgres only thing. At least I didn't encounter it anywhere else yet.
@DominikCzekański: But in many other DBMS you could use (yet another) CASE expression to get something with the same effect of FILTER. I edited the answer to include that as well.
@stickybit looking at the documentation, FILTER doesn't seem to be a Postgres extension (it is a keyword in ANSI-SQL, and there is no NOTE in the aggregate documentation) Maybe Postgres is the only DBMS that actually implemented it?
Filter is standard SQL, but not implemented by all types of databases. modern-sql.com/feature/filter
|

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.