Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

279
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda