Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

273
Views
PSQL Except vs Except All

I have the following schema:

create table Took(
sID integer,
oID integer,
grade integer);



INSERT INTO Took VALUES
    (1, 1, 90),
    (1, 2, 100),
    (2, 1, 90),
    (2, 3, 80),
    (2, 4, 85)
;

I have the following query as well:

(select sid from took) except all (select sid from took where grade < 90);

and this produces the output 1,1,2 which is expected since the grade values are >= 90 in this case. However, when I remove the all clause to

select sid from took) except (select sid from took where grade < 90);

The output is just 1. I know the all determines whether duplicates exist so in this case I expect the output to be 1,2 and not just 1. So whats going on?

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

From PSQL documentation, when EXCEPT is used alone:

The EXCEPT operator computes the set of rows that are in the result of the left SELECT statement but not in the result of the right one.

But, when ALL is used along with EXCEPT:

The result of EXCEPT does not contain any duplicate rows unless the ALL option is specified. With ALL, a row that has m duplicates in the left table and n duplicates in the right table will appear max(m-n,0) times in the result set.

In your example, the result of left SELECT query will be the sid of all rows.

test=# select sid from took;
 sid
-----
   1
   1
   2
   2
   2
(5 rows)

And, the result of right SELECT query will be last two rows having grade<90.

test=# select sid from took where grade < 90;
 sid
-----
   2
   2
(2 rows)

Now, running query with only EXCEPT:

test=# (select sid from took) except (select sid from took where grade < 90);
 sid
-----
   1
(1 row)

What happened here is,

  1. We took the result of left SELECT query(5 rows).
  2. Then, remove all matching rows containing result of right SELECT query(i.e. sid=2), we are left with 2 rows with sid=1.
  3. Now, since there will be no duplicate, so final result will be 1 row with sid=1.

This is the explanation for the result you got.

Now, running query with EXCEPT ALL:

test=# (select sid from took) except all (select sid from took where grade < 90);
 sid
-----
   1
   1
   2
(3 rows)

In this case, we just remove the result of right SELECT query form the result of left SELECT query.

Hope, this helps.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!