PostgreSQL Prático/DML/Sub Consultas

4.3 – Sub consultasEditar

São consultas dentro de consultas.

Subconsulta escalar é um comando SELECT comum, entre parênteses, que retorna exatamente um registro, com um campo.

 select nome, (select max(preco) from produtos where codigo=1) as "maior preço" from produtos;

 SELECT * FROM tabela1 WHERE tabela1.col1 = 
   (SELECT col2 FROM tabela2 WHERE col2 = valor);

 SELECT name FROM customer WHERE customer_id NOT IN ( SELECT customer_id FROM salesorder );

 SELECT 'test' AS test, id FROM (SELECT * FROM books) AS example_sub_query;

 SELECT firstname, state, 
   CASE
     WHEN state = 'PA' THEN 'close'
     WHEN state = 'NJ' OR state = 'MD' THEN 'far'
   ELSE 'very far'
 END AS distance
 FROM friend;


Expressões de Sub Consultas


EXISTS

SELECT campo1 FROM tabela1 WHERE EXISTS
  (SELECT 1 FROM tabela2 WHERE campo2 = tabela1.campo2);


Combinando CASE e EXISTS

CREATE TEMPORARY TABLE frutas (id SERIAL PRIMARY KEY, nome TEXT);
INSERT INTO frutas VALUES (DEFAULT, 'banana');
INSERT INTO frutas VALUES (DEFAULT, 'maçã');


CREATE TEMPORARY TABLE alimentos (id SERIAL PRIMARY KEY, nome TEXT);
INSERT INTO alimentos VALUES (DEFAULT, 'maçã');
INSERT INTO alimentos VALUES (DEFAULT, 'espinafre');


SELECT nome, CASE WHEN EXISTS (SELECT nome FROM frutas WHERE nome=a.nome)
               THEN 'sim'
               ELSE 'não'
           END AS fruta
FROM alimentos a;

IN

SELECT nome, CASE WHEN nome IN (SELECT nome FROM frutas)
                THEN 'sim'
                ELSE 'não'
           END AS fruta
FROM alimentos;


NOT IN

ANY/SOME

SELECT nome, CASE WHEN nome = ANY (SELECT nome FROM frutas)
                THEN 'sim'
                ELSE 'não'
           END AS fruta
FROM alimentos;


CASE WHEN

EXEMPLO1

create table amigos(
       codigo serial primary key,
       nome char(45),
       idade int
);


insert into amigos (nome, idade) values ('João Brito', 25);
insert into amigos (nome, idade) values ('Roberto', 35);
insert into amigos (nome, idade) values ('Antônio', 15);
insert into amigos (nome, idade) values ('Francisco Queiroz', 23);
insert into amigos (nome, idade) values ('Bernardo dos Santos', 21);
insert into amigos (nome, idade) values ('Francisca Pinto', 22);
insert into amigos (nome, idade) values ('Natanael', 55);


select nome,
       idade,
       case
           when idade >= 21 then 'Adulto'
           else 'Menor'
       end as status
from amigos order by nome;


-- CASE WHEN cria uma coluna apenas para exibição


EXEMPLO2


create table amigos(
       codigo serial primary key,
       nome char(45),
       estado char(2)
);


insert into amigos (nome, estado) values ('João Brito', 'CE');
insert into amigos (nome, estado) values ('Roberto', 'MA');
insert into amigos (nome, estado) values ('Antônio', 'CE');
insert into amigos (nome, estado) values ('Francisco Queiroz', 'PB');
insert into amigos (nome, estado) values ('Bernardo dos Santos', 'MA');
insert into amigos (nome, estado) values ('Francisca Pinto', 'SP');
insert into amigos (nome, estado) values ('Natanael', 'SP');


select nome,
               estado,
               case
                       when estado = 'PB' then 'Fechado'
                       when estado = 'CE' or estado = 'SP' then 'Funcionando'
                       when estado = 'MA' then 'Funcionando a todo vapor'
                       else 'Menor'
               end as status
from amigos order by nome;


Mostrar cada nota junto com a menor nota, a maior nota, e a média de todas as notas.

SELECT nota,
      (SELECT MIN(nota) FROM notas) AS menor,
      (SELECT MAX(nota) FROM notas) AS maior,
      (ROUND(SELECT AVG(nota) FROM notas)) AS media
FROM notas;