Podemos também ordenar os resultados de uma consulta por coluna, em ordem crescente ou decrescente.
Primeiramente, vamos inserir mais uns produtos na tabela, assim:
insert into produtos (codigo, nome, descricao, preco, qtd_estoque) values
(6, 'Detergente', 'Detergente líquido 500 ml', 1.89, 32),
(7, 'Leite Integral', 'Leite integral caixa de 1 litro', 4.60, 70),
(8, 'Refrigerante', 'Garrafa de refrigerante de 600 ml', 3.70, 14),
(9, 'Refrigerante', 'Garrafa de refrigerante de 1 litro', 6.89, 16),
(10, 'Refrigerante', 'Lata de refrigerante de 350 ml', 2.99, 45);
-- Esse insert é a parte, para vermos como funciona valores null,
-- pois a descrição não foi especificada.
insert into produtos (codigo, nome, preco, qtd_estoque) values (11, 'Margarina', 3.20, 8);
-- Depois dê esse select:
select * from produtos;
Para pegar os valores ordenados, faça assim:
select * from produtos order by nome; -- Por padrão, ele ordena em ordem crescente
Invertendo a ordem, com outra coluna:
select * from produtos order by qtd_estoque desc;
Podemos filtrar também, dessa forma:
select nome, preco from produtos order by nome;
Note que os refrigerante ficaram fora de ordem de preços, para isso, fazemos uma segunda ordenação dentro da primeira:
select nome, preco from produtos order by nome, preco;
No caso, ele ordenará primeiro por nome, e dentro dos nomes, por preço.
Faça essa ordenação:
select nome, descricao from produtos order by descricao;
Note que o último item é a margarina, que está com o valor null. Para os valores null aparecer antes, faça assim:
select nome, descricao from produtos order by descricao nulls first; -- Pode ser last também
Podemos usar o order junto com o where também, por exemplo:
select nome, preco from produtos where preco > 10.00 order by preco asc;
-- Invertendo a ordem:
select nome, preco from produtos where preco > 10.00 order by preco desc;
PS: O order vem depois do where.
O limit e o offset permitem obter uma parte específica das linhas retornadas por uma consulta SQL.
É recomendado usar o order by com o limit e o offset, mas ele não é obrigatório.
Vamos ver todos os produtos cadastrados:
select * from produtos order by preco;
Para vermos os quatro produtos mais baratos:
select * from produtos order by preco limit 4;
Nesse caso acima ele só mostrará os quatro produtos mais baratos.
Para visualizarmos do terceiro ao quinto mais caro, usamos o offset dessa forma:
select * from produtos order by preco desc limit 3 offset 2; -- Desconsidera os dois primeiros, contando a partir do terceiro.
O offset pode ser usado sem depender do limit, nesse comando ele mostra a partir do terceiro até o fim:
select * from produtos order by preco desc offset 2;
Os valores padrões dos comandos limit e offset são all
e 0
, respectivamente, mas estes são dispensáveis colocar, geralmente.
Ao usar o limit sem o order, pode dar alguns problemas da exibição, por exemplo:
select * from produtos limit 5;
No caso acima, ele ordena pelo valor padrão, que é a chave primária.
Os operadores de comparação são usados para comparar dois valores e retornar um valor booleano, dependendo do resultado da comparação. Os operadores são os mesmos da maioria das linguagens de programação: <
, >
, <=
, >=
, =
(nesse caso é um igual só) e !=
(ou <>
).
Vamos ver um exemplo de consulta SQL com isso:
select nome, preco from produtos where preco > 12.00;
Outro exemplo:
select nome, qtd_estoque from produtos where qtd_estoque <= 20;
Mais um, com o operador lógico and
:
select nome, qtd_estoque from produtos where qtd_estoque <= 20 and qtd_estoque > 10;
Podemos também usar os operadores lógicos or
e not
, mas veremos isso mais pra frente.
Vamos trazer todos os produtos:
select nome, qtd_estoque from produtos;
Para não mostrar nenhum cadastro de refrigerante, fazemos assim:
select nome, qtd_estoque from produtos where nome != 'Refrigerante';
Temos também o operador like
, para procurar algo parecido, assim:
select nome from produtos where nome = 'Refrigerante';
select nome from produtos where nome like '%a';
select nome from produtos where nome like 'L%';
A porcentagem significa de 0 a infinitos caracteres, podemos usar o _
para exigir apenas um caractere antes ou depois, e podemos combinar a porcentagem e o underline, por exemplo:
select nome from produtos where nome like 'Luvas_%';
PS: Diferente de outros bancos, o operador like diferencia maiúsculas e minúsculas no PostgreSQL. Para não diferenciar, use ilike
no lugar.
O operador between
permite visualizar os cadastros dentro de um intervalo especificado dentro do mesmo. Ele é usado em conjunto com o and
. Podemos usar também uma negação com not
para ele não mostrar dados dentro do intervalo especificado.
Veja uma consulta padrão numa tabela:
select * from produtos;
Veja o uso dos operadores, com a cláusula where:
select nome, preco from produtos where preco between 10.00 and 20.00;
Mais um exemplo:
select nome, preco from produtos where
preco between 3.50 and 5.00 or
preco between 10.00 and 20.00;
Outro exemplo:
select nome, preco, qtd_estoque from produtos where
preco between 2.00 and 6.00 and
qtd_estoque < 10;
Também podemos usar negação, dessa forma:
select nome, preco, qtd_estoque from produtos
where preco between 5.00 and 12.00;
-- Com negação:
select nome, preco, qtd_estoque from produtos
where preco not between 5.00 and 12.00;
Com a declaração update
podemos atualizar registros em uma tabela, como por exemplo, alguma informação cadastrada de forma errônea.
Digite esse comando para ver os dados da tabela:
select * from produtos;
No exemplo, o registro Margarina
não tem descrição (está como null). Para atualizar o campo, fazemos assim:
update produtos set descricao = 'Pote de margarina vegetal' where codigo = 11;
PS: Sempre use a cláusula where ao usar o update, para não atualizar todos os cadastros por acidente.
Vamos alterar o preço de um produto:
update produtos set preco = 3.95 where nome = 'Sabonete';
PS: O recomendado é a cláusula where ser usada no id, mas como visto, podemos usar outras colunas, no entanto, o comando acima atualizaria o preço de todas as ocorrências contendo Sabonete
no banco.
Vamos fazer mais esse update, com cálculo:
update produtos set qtd_estoque = qtd_estoque - 4 where preco > 15.00;
Como dissemos, sem a cláusula where temos que ter cuidado, mas nesse caso, faremos uma atualização do preço de todos os produtos da tabela, assim:
update produtos set preco = round(preco * 1.10, 2); -- É o mesmo que acrescentar 10% ao preço.
Uma das tarefas mais comuns em bancos de dados é apagar registros em uma tabela. Para isso usamos o delete
e o truncate
, cada um com suas diferenças.
Vamos cadastrar mais alguns itens extras no nosso banco como exemplo:
insert into produtos (codigo, nome, descricao, preco, qtd_estoque) values
(12, 'Sabão em Pó', 'Caixa de sabão em pó de 1/2 Kg', 12.50, 5),
(13, 'Biscoito', 'Pacote de biscoito integral 110 g', 3.45, 16),
(14, 'Manteiga', 'Pote de manteiga 250 g', 8.70, 5);
Dê um select em produtos para ver os registros.
Para deletar um registro, usamos o código dele com where, de forma semelhante com o update, por exemplo:
delete from produtos where codigo = 12;
Podemos excluir também pelo nome:
delete from produtos where nome = 'Manteiga';
Para excluir vários registros, fazemos assim:
delete from produtos where qtd_estoque <= 5;
No caso, ele excluirá todos os registros com menos de 5 unidades.
PS: Cuidado ao utilizar condições que afetem mais de uma linha. E lembre-se que um delete sem where excluiria todos os registros da tabela.
Para excluir todos os registros de uma tabela, inclusive, é melhor utilizar o truncate
. Veja esse exemplo, na tabela pedidos:
truncate table pedidos;
Carregue novamente os dados na tabela pedidos, pois usaremos em aulas seguintes:
insert into pedidos (cod_cliente, cod_produto, qtd_vendida) values
(1, 2, 3),
(2, 3, 2),
(1, 3, 4),
(2, 6, 3),
(2, 5, 2),
(3, 8, 5);
As funções de agregação em SQL são usadas para computar um valor único a partir de um conjunto de valores de entrada.
As funções básicas de agregação são essas:
Função | O que Ela Faz |
---|---|
count(x) |
Conta itens em uma coluna |
max(x) |
Retorna o maior valor |
min(x) |
Retorna o menor valor |
avg(x) |
Retorna a média dos valores |
sum(x) |
Retorna a soma dos valores |
Usando a função count
:
select count(*) as "Quant. Clientes" from clientes; -- Use aspas duplas nesse exemplo
select count(nome) from clientes;
select count(nome) from produtos;
select count(distinct nome) from produtos; -- O distinct não conta valores repetidos
select count(*) from produtos where preco >= 10.00;
PS: Com o nome de uma coluna, ele não conta valores nulos.
Usando as outras funções:
select max(preco) from produtos;
select min(preco) from produtos;
select sum(preco) from produtos;
select avg(preco) from produtos;
Para melhorar a visualização de valores com muitas casas decimais, usamos o round
, assim:
select round(avg(preco), 2) from produtos;
select round(avg(preco), 2) from produtos where nome = 'Refrigerante';
PS: Não é possível usar esses valores de agregação com nome de registros, esse comando abaixo, por exemplo, daria erro:
select sum(preco), nome from produtos;
Isso será corrigido mais pra frente, usando as cláusulas group
e having
.
Podemos dar um nome diferente a uma coluna ou tabela ao realizar uma consulta usando um alias. Ele não altera os nomes no banco, somente na visualização.
Veja alguns exemplos abaixo:
select nome as "Produto" from produtos where qtd_estoque > 5; -- Aspas duplas
select nome as "Nome do Cliente", sobrenome as "Sobrenome do Cliente" from clientes as cl;
select codigo as "Código do Pedido", qtd_vendida as "Quantidade" from pedidos as p order by "Quantidade" desc;
Lembrando que os aliases em tabelas só aparecem em inner joins entre duas ou mais tabelas.
PS: Podemos omitir o as
em alguns casos, por exemplo:
select nome "Produto" from produtos;