Introdução a Linguagem SQL: Comandos Básicos e Avançados – Parte 1 - Diego Macêdo
Introdução a Linguagem SQL: Comandos Básicos e Avançados – Parte 1
O SQL, Structured Query Language, é a linguagem utilizada pelos Banco de Dados Relacionais (BDR) modernos, sendo ela, as vezes, a única forma de você interagir com o BD em si. Todas as telas gráficas e programas que administram os BDs, nada mais é que um tradutor da funcionalidades do SQL. Eles realizam as ações que o usuário realiza na parte gráfica e converte os comandos para o SQL interagir com o BD.
Neste ponto, você pode estar pensando que você não é um programador e aprender uma linguagem de programação não é uma das suas coisas. Felizmente, o SQL é uma linguagem simples. Tem um número limitado de comandos, que são de leitura fácil e estruturados, quase como o inglês.
Se você não tem a mínima noção sobre o assunto de Banco de Dados, provavelmente você vai querer ler uma postagem que fiz recentemente dando uma introdução sobre os principais termos utilizados nesta área "Fundamentos da Administração de Dados: Tabelas, Entidades, Relação, Colunas, Atributos, Linhas, Registros, Tuplas, Índices, Chaves e Relacionamentos".
Caso já tenha conhecimento, pode pular para o próximo tópico da postagem.
Suponha que você tenha um BD simples para manter o inventário que foi projetado para uma loja de conveniência. Uma das tabelas no banco de dados pode conter os preços dos itens em suas prateleiras, indexados por números de referência únicos que identificam cada item. Provavelmente, você teria uma tabela simples com nome de "Preços". Se você precisa identificar todos os itens que tenham um preço acima de R$ 5,00, você pode recuperar a partir do seu BD esta informação utilizando o SQL fazendo uma consulta.
Realizando CONSULTAS (SELECT)
Antes de irmos direto ao comando, vamos analisar o que queremos fazer com a tabela. Imagine que você quer "selecionar todos os números de série de sua tabela de preços acima de R$ 5,00." Se formos transformar isto em SQL, será tão simples quanto. Veja o comando:
SELECT NumeroSerie
WHERE Preco > 5;
Muito simples, não? Se você ler o comando, perceberá que é similar ao que queríamos antes.
Perceba que o comando será sempre similar ao nosso exemplo. Vamos a estrutura genérica do comando.
SELECT (atributos da tabela) FROM (nome da tabela) WHERE (condição);
Onde os atributos da tabela podem ser escolhidos de qualquer forma: um único atributo, vários ou todos. Veja os exemplos abaixo e descubra o que eles fazem.
SELECT nome,cargo,salario FROM tbl_funcionarios WHERE salario > 1000;
SELECT * FROM jogadores WHERE time = "Flamengo";
Já vimos como selecionar os atributos que queremos, agora vamos dar uma olhada nas condições do WHERE. É nele que "filtramos" os atributos escolhidos. O WHERE é opcional, sendo assim você omití-lo, então você terá todos os registros com os atributos escolhidos. As condições mais comuns são:
!= ou <> (diferente)
LIKE (similar a)
BETWEEN (entre X e Y)
IN (vários valores dentro da lista)
XOR (mistura do OR com
IS (valores iguais)
Com exceção dos dois últimos, todos possuem a seguinte sintaxe:
<expressao1> operador <expressao2>
Veja esta tabela para ajudar a entender melhor algumas condições:
<expressao1> Operador <expressao2> Resultado
Verdadeiro AND Falso Falso
Verdadeiro AND Verdadeiro Verdadeiro
Falso AND Verdadeiro Falso
Verdadeiro OR Falso Verdadeiro
Verdadeiro OR Verdadeiro Verdadeiro
Falso OR Verdadeiro Verdadeiro
Verdadeiro XOR Verdadeiro Falso
Verdadeiro XOR Falso Verdadeiro
Falso XOR Verdadeiro Verdadeiro
Se a qualquer das anteriores condições lhe ante-pusermos o operador NOT o resultado da operação será o contrário ao devolvido sem o operador NOT.
O último operador denominado IS se emprega para comparar duas variáveis de tipo objeto <Objeto1> IS <Objeto2>. Este operador devolve verdadeiro se os dois objetos forem iguais.
Vou utilizar um mesmo exemplo, só variando as condições. Perceba que será fácil entender o que o comando irá retornar na consulta. Veja alguns exemplos de utilização dessas condições:
SELECT nome,cargo,salario FROM tbl_funcionarios WHERE nome = "Diego";
SELECT nome,cargo,salario FROM tbl_funcionarios WHERE salario < 7000;
SELECT nome,cargo,salario FROM tbl_funcionarios WHERE salario >= 1000;
SELECT nome,cargo,salario FROM tbl_funcionarios WHERE salario <= 5500;
SELECT nome,cargo,salario FROM tbl_funcionarios WHERE nome LIKE "Di*";
SELECT nome,cargo,salario FROM tbl_funcionarios WHERE salario BETWEEN 1000 AND 5000;
SELECT nome,cargo,salario FROM tbl_funcionarios WHERE salario > 1000 AND salario < 5000;
SELECT nome,cargo,salario FROM tbl_funcionarios WHERE (salario > 1000 AND salario < 5000) OR (nome = "Diego" AND cargo = "Analista de Sistemas");
SELECT nome,cargo,salario FROM tbl_funcionarios WHERE NOT nome = "Diego";
SELECT nome,cargo,salario FROM tbl_funcionarios WHERE nome != "Diego";
SELECT nome,cargo,salario,cidade FROM tbl_funcionarios WHERE cidade IN("Maceió", "São Paulo", "Rio de Janeiro")
SELECT Name, Category, InStock, OnOrder FROM Books WHERE Category='Fiction' XOR InStock IS NULL BY Name;
Falta de exemplos não é. 😉
CRIANDO tabelas (CREATE TABLE)
Para trabalharmos com BD, precisamos das tabelas que armazenam os dados. Para isso, precisamos criá-las, seguinte a estrutura abaixo:
nome_atributo tipo_dado opções,
nome_atributo tipo_dado opções);
Os atributos das tabelas precisam ser definidos com os seus tipos, seguindo os tipos abaixo:
Tipo de Dados Longitude Descrição
BINARY 1 byte Para consultas sobre tabela anexa de produtos de banco de dados que definem um tipo de dados Binário.
BIT 1 byte Valores Sim/Não ou True/False
BYTE 1 byte Um valor inteiro entre 0 e 255.
COUNTER 4 bytes Um número incrementado automaticamente (de tipo Long)
CURRENCY 8 bytes Um inteiro escalável entre 922.337.203.685.477,5808 e 922.337.203.685.477,5807.
DATETIME 8 bytes Um valor de data ou hora entre os anos 100 e 9999.
SINGLE 4 bytes Um valor em ponto flutuante de precisão simples com uma classificação de – 3.402823*1038 a -1.401298*10-45 para valores negativos, 1.401298*10- 45 a 3.402823*1038 para valores positivos, e 0.
DOUBLE 8 bytes Um valor em ponto flutuante de dupla precisão com uma classificação de – 1.79769313486232*10308 a -4.94065645841247*10-324 para valores negativos, 4.94065645841247*10-324 a 1.79769313486232*10308 para valores positivos, e 0.
SHORT 2 bytes Um inteiro curto entre -32,768 e 32,767.
LONG 4 bytes Um inteiro longo entre -2,147,483,648 e 2,147,483,647.
LONGTEXT 1 byte por caractere De zero a um máximo de 1.2 gigabytes.
LONGBINARY Segundo se necessite De zero 1 gigabyte. Utilizado para objetos OLE.
TEXT 1 byte por caractere De zero a 255 caracteres.
A tabela de sinônimos dos tipos de dados:
Tipo de Dado Sinônimos
STRING – VARCHAR
VARIANT (Não Admitido) VALUE
Vejamos alguns exemplos de comandos prontos:
CREATE TABLE tblprofessor(
codprofessor INTEGER CONSTRAINT primarykey PRIMARY KEY,
nome TEXT (50),
endereco TEXT (50)
telefone TEXT (15),
sexo TEXT (1),
observacao TEXT (100));
CREATE TABLE tblNotas(
codaluno INTEGER CONSTRAINT tblalunosFK REFERENCES tblalunos,
Codcurso INTEGER CONSTRAINT tblcursosFK REFERENCES tblcursos,
Nota INTEGER,
Ano TEXT (4),
Bimestre INTEGER);
CREATE TABLE tblalunos(
codaluno INTEGER CONSTRAINT primarykey PRIMARY KEY,
nomepai TEXT (50),
nomemae TEXT (50),
periodo TEXT (1),
serie TEXT (10),
numero TEXT (5),
observacao TEXT (100),
ativo BIT);
INSERINDO registros (INSERT INTO)
Parar cadastrar os dados em nossas tabelas, utilizamos a estrutura abaixo:
INSERT INTO nome_tabela (
nome_campo1, nome_campo2, ..., nome_campoN)
valor_campo1, valor_campo2, ..., valor_campoN
INSERT INTO Pessoas VALUES (4,'Nilsen', 'Johan', 'Bakken 2', 'Stavanger');
INSERT INTO agenda (nome, numero) VALUES ("John Doe", "555-1234");
INSERT INTO PAÍSES VALUES ('Taiwan', 'TW', 'Ásia');
INSERT INTO DEPARTAMENTOS (NUM_DEP, NOME_DEP, ADMRDEPT) VALUES ('E31', 'ARQUITETURA', 'E01');
INSERT INTO DEPARTAMENTOS (NUM_DEP, NOME_DEP, ADMRDEPT) VALUES ('B11', 'COMPRAS', 'B01'), ('E41', 'ADMINISTRAÇÃO DE BANCO DE DADOS', 'E01');
DELETANDO/EXCLUINDO registros (DELETE)
O comando DELETE é responsável pela exclusão de registros que não queremos mais dentro de nossas tabelas. Segue a estrutura básica:
Lembra que olhamos alguns operadores para ser utilizado junto ao WHERE do SELECT? Ele continua valendo aqui. Veja os exemplos:
DELETE FROM funcionarios WHERE id_funcionario = 86;
DELETE FROM funcionarios WHERE id_funcionario < 100;
DELETE FROM funcionarios WHERE func_nome = "Diego";
ATUALIZANDO os registros (UPDATE)
Quando queremos atualizar/modificar os valores de algum registro na tabela, precisamos dar um UPDATE. O WHERE continua presente! Veja a estrutura básica:
UPDATE tabela SET coluna = valor_novo WHERE condição
UPDATE funcionarios SET salario = 5000 WHERE id_funcionario = 45;
UPDATE funcionarios SET salario = 7400, nome = "Diego Macêdo" WHERE id_funcionario = 1;
UPDATE funcionarios SET salario = 545 WHERE salario = 510;
UPDATE Persons SET Address='Nissestien 67', City='Sandnes' WHERE LastName='Tjessem' AND FirstName='Jakob';
Dica importante para este comando, é não esquecer do WHERE, ou então ele irá alterar todos os registros da sua tabela. Afinal, você não filtrou em quais registros ele irá afetar, não é verdade?
ORDENANDO os registros de uma CONSULTA (ORDER BY)
Já aprendemos a estrutura do SELECT, então vamos acrescentar algumas funcionalidades a este comando e melhorar ainda mais nossas consultas com o ORDER BY, responsável por ordernar nosso resultado capturado de forma crescente ou decrescente baseado nas colunas que quisermos. O WHERE é opcional. Sintaxe básica é:
SELECT atributos FROM tabela ORDER BY atributo {ASC / DESC};
Os nomes ASC e DESC são opcionais, mas por padrão o ASC é utilizado, pois ele define de forma ascendente (crescente) a lista. O DESC faz o inverso, decrescente.
SELECT nome, salario, cargo FROM funcionarios ORDER BY nome;
SELECT nome, salario, cargo FROM funcionarios ORDER BY nome ASC;
SELECT nome, salario, cargo FROM funcionarios ORDER BY nome DESC;
SELECT nome, salario, cargo FROM funcionarios ORDER BY nome ASC, salario DESC;
SELECT nome, salario, cargo FROM funcionarios WHERE salario > 5000 ORDER BY cargo ASC, nome ASC;
Agora que já vimos os comandos básicos para o SQL, vamos começar a tornar isto mais avançado interessante. Mas não se preocupe. Se você conseguiu entender bem esta base, com certeza entenderá o restante. Lembrando que estou sempre disposto a ajudar com as dúvidas.
Comandos SQL Avançados
JUNTANDO tabelas (JOIN)
Este comando serve para juntar duas ou mais tabelas, baseadas em uma relação entre algumas colunas das tabelas envolvidas, através da utilização das chaves primárias e estrangeiras.
Para trabalhar com os próximos comandos, irei demonstrar aqui algumas tabelas que irão ser utilizadas para fazer mais sentido aos resultados. Vejamos elas:
TBL_FUNCIONARIO
id_func (PK) nome salario id_depto (FK)
1 Diego 2500 345
2 Maria 5500 456
3 João 4000 567
4 José 8000 123
5 Marcos 4500 567
6 Cristina 1000 (NULL)
TBL_DEPTO
id_depto (PK) nome ramal
123 Diretoria 9999
456 Gerência 8888
345 T.I. 5555
567 Comercial 6666
987 Vendas 1111
Agora vamos continuar os estudos.
Existem diferentes tipos de JOINS, os quais são:
JOIN – Retorna os registros das tabelas quando pelo menos um deles se relacionam;
LEFT JOIN – Retorna todos os registros da tabela da esquerda, mesmo que não exista combinação com alguma linha da tabela da direita;
RIGHT JOIN – O inverso do LEFT JOIN em relação as tabelas;
FULL JOIN – Retorna todos os registros, mesmo quando não existe uma relação entre as tabelas;
Vamos estudar cada um deles agora.
Retorna os registros quando existe pelo menos uma relação entre as tabelas. Se executarmos o comando abaixo:
SELECT f.nome, f.salario, d.nome AS depto
FROM tbl_funcionarios AS f
INNER JOIN tbl_depto AS d
ON f.id_depto = d.id_depto
ORDER BY d.nome ASC, f.nome ASC;
Dica: Quando utilizamos o "AS", ele definirá um apelido para o atributo ou tabela, o qua facilita o entendimento de onde estamos selecionando os dados. Veja que "f.nome" é o nome da tabela tbl_funcionarios, f.salario é o atributo salário da tbl_funcionarios e o d.nome é o nome do departamento da tbl_depto. Bem útil para facilitar o entendimento.
Teremos a seguinte resposta desta consulta:
nome salario depto
João 4000 Comercial
Marcos 4500 Comercial
José 8000 Diretoria
Maria 5500 Gerência
Diego 2500 T.I.
Retorna todos os registros da tabela da esquerda, mesmo que não exista combinação com alguma linha da tabela da direita. Vejamos um exemplo de comando:
LEFT JOIN tbl_depto AS d
ORDER BY f.nome ASC;
Cristina 1000 (NULL)
Com esta consulta, pegamos a funcionária Cristina que não pertence a nenhum departamento.
Retorna todos os registros da tabela da direita, mesmo que não exista combinação com alguma linha da tabela da esquerda. Veja o comando:
SELECT f.nome, f.salario, d.nome AS depto
FROM tbl_funcionarios AS f
RIGHT JOIN tbl_depto AS d ON f.id_depto = d.id_depto
ORDER BY f.nome ASC
Resultado seria este:
(NULL) (NULL) Vendas
Perceba que ele capturou o departamento chamado "Vendas", mas que não tinha nenhum funcionário se relacionando com ele.
UNIÃO de tabelas (UNION/UNION ALL)
O comando de UNION é usado para combinar os resultados de duas ou mais tabelas. Perceba que cada SELECT deve-se ter o mesmo número de colunas de cada tabela, incluindo o mesmo tipo de dados, assim como devem estar na mesma ordem. Veja a sintaxe:
SELECT colunas FROM tabela1
SELECT colunas FROM tabela2;
Por padrão, o UNION captura apenas valores distintos. Caso queira que ele capture os valores repetidos, deve-se usar o UNION ALL:
TBL_EMPREGADOS1
E_Nome
TBL_EMPREGADOS2
O nosso resultado ao utilizar o UNION simples:
SELECT E_Nome FROM tbl_empregados1
SELECT E_Nome FROM tbl_empregados2;
Se utilizarmos o UNION ALL, irá aparecer os valores repetidos:
Constantes (Constraints)
As constantes são utilizadas para determinar o limite do tipo de dados poderão ser utilizados em uma tabela. Elas podem ser utilizadas quando criamos as tabelas (com o comando CREATE TABLE) ou após criarmos (com o ALTER TABLE).
Veremos com mais detalhes abaixo cada uma delas.
Com esta constante, podemos definir que uma coluna NÃO poderá receber valores nulos, ou seja, ficar sem valor algum preenchido. Caso ele esteja definido, não poderemos inserir um registro sem ter a coluna preenchida com algo ou atualizá-la (UPDATE) sem ter um valor definido. Veja o exemplo de como utilizá-lo na criação de uma tabela:
sobrenome varchar(255) NOT NULL,
Sua função é identificar unicamente cada registro em uma tabela do BD. Esta constante e a PRIMARY KEY são responsáveis pela unicidade dos valores de uma ou mais colunas. Toda PRIMARY KEY automaticamente tem a constante UNIQUE definida por padrão. Perceba que você pode ter várias colunas com a constante UNIQUE definida, mas somente uma PRIMARY KEY por tabela. Veja o exemplo abaixo:
UNIQUE (id_pessoa)
Utilizando após ter a tabela criada, podemos fazer assim:
ADD UNIQUE (id_pessoa);
Para remover a constante UNIQUE:
DROP INDEX id_pessoa;
Já vimos aqui que a chave primaria (Primary Key – PK) é responsável por identificar unicamente cada registro de uma tabela do BD. Toda chave primária deve ter um valor único e não pode conter valores nulos (NULL). Cada tabela deve ter UMA chave primária. Veja o exemplo de como utilizamos na hora de criar uma tabela:
Definindo a chave primária após ter criado a tabela:
ADD PRIMARY KEY (id_pessoa);
Removendo a chave primária:
As chaves estrangeiras são responsáveis pelos relacionamentos entre as tabelas. Se você já entendeu os comandos de JOIN visto aqui na postagem lá na parte superior, já viu a FK sendo utilizada. A FK é responsável por fazer uma referência a PK de outra tabela. Caso queira entender um pouco mais sobre relacionamentos em BD. Vejamos o exemplo na hora de criarmos uma tabela:
id_cidade int
PRIMARY KEY (id_pessoa),
FOREIGN KEY (id_cidade) REFERENCES cidades(id_cidade)
A FK criada na coluna "id_cidade" faz referência a coluna "id_cidade" da tabela "cidades".
Para definirmos após a tabela estar criada:
ADD FOREIGN KEY (id_cidade)
REFERENCES cidades(id_cidade);
Para removermos esta chave estrangeira:
DROP FOREIGN KEY id_cidade;
O CHECK é utilizado para limitar a faixa de valores que pode ser colocado em uma coluna. No exemplo abaixo, estamos definindo que os valores para a coluna "id_pessoa" será maior que zero:
CHECK (id_pessoa>0)
Alterando uma tabela já criada e inserindo o CHECK:
ADD CONSTRAINT teste
CHECK (id_pessoa>0);
DROP CONSTRAINT teste;
Utilizado para inserir um valor padrão em uma coluna, caso nenhum outro seja informado na hora do INSERT.
cidade int DEFAULT "Maceió",
data_cadastro date DEFAULT GETDATE()
Após a tabela criada, podemos fazer assim:
ALTER cidade SET DEFAULT "Maceió";
ALTER cidade DROP DEFAULT;
Por enquanto vamos parar por aqui, pois já é assunto demais. Mas irei continuar com outros comandos importantes em outra postagem. Abraços e não deixem de compartilhar com seus amigos nas redes sociais e assinar meu blog para ficar por dentro das atualizações constantes que eu venho fazendo ultimamente aqui.
24 Responses to "Introdução a Linguagem SQL: Comandos Básicos e Avançados – Parte 1"
Que material bem explicado. Obgda e parabens!
17 de agosto de 2018 às 15:56
Excelente introdução, parabéns !!!
15 de outubro de 2018 às 11:40
Muito legal! Parabéns! Podemos compartilhar no Zap?
15 de outubro de 2018 às 11:46
Oi Ederbal. Fique a vontade para compartilhar o link onde quiser. Abs!
Lucas Marcus Bittencourt disse:
16 de janeiro de 2018 às 18:02
Muito bom, explicou exatamente da maneira que eu queria, rsrsr. Ótimo trabalho, parabéns!
22 de abril de 2017 às 09:25
Muito bom o trabalho, pratico e objetivo.
nhala disse:
15 de abril de 2017 às 07:04
Dei com sítio ao acaso, e gostei muito.
Tudo tao objetivo, parabéns!
Diego, sou uma pessoa sem condições de pagar um bom curso de informatica no momento. sou um iniciante no access e na sql, se vc puder me informar onde posso encontrar via internet uma apostila "GRATIS" com exemplos bem didaticos dos dois cursos, pois ja vasculhei e só encontro exemplos não bem explicativos. Tenho muito interesse e vontade de crescer dentro da empresa, e com essas apostilas terei mais condições para isso.
Obrigado, mesmo se não puder. sei que vc deve ser muito solicitado e com pouco tempo para atender a todos que te pedem sos.
Orlando, pesquisa no Youtube algumas vídeo aulas. Quem sabe você não aprende melhor por lá?!?!
Comandos básicos no MySQL | Thiago Quevedo disse:
17 de outubro de 2014 às 01:49
[…] – http://www.diegomacedo.com.br/introducao-a-linguagem-sql-comandos-basicos-e-avancados-parte-1/ […]
CARSON ADRIANO disse:
Muito boa a explicação e fácil entendimento
Aldeci Gomes disse:
13 de Maio de 2014 às 09:17
Muito bom seu artigo, porém se permite, objeto flutuante (lateral esquerda) está ficando sobre o texto dificultando a leitura.
31 de Maio de 2014 às 09:26
Já resolvi o problema fazendo o ajuste dele. Muito obrigado!
Caro Diego, presto Tec.em redes e meu professor é ruim demais , cara estou com muita duvida em aplicar 1FN,2FN e 3FN, comecei agora e não consigo acompanhar o raciocínio do professor , fora que a maioria da classe não compreende, por favor tem como ensinar um jeito mais logico de aplica-las.
Elias, segue o link: http://www.diegomacedo.com.br/normalizacao-de-um-banco-de-dados/
Hernani de Jesus R.Pereira disse:
17 de Maio de 2013 às 08:15
Adorei a explicação,simples mas efícaz, estou utilizando tudo isso para estudar.Estou no 2º ano do curso de Engenharia de Sistemas e Informatica.Gostaria de ter informações sobre modelo EA e ER para SGBD,pois estou com muita dúvida…obrigado
Tâmara Francielle Brito de Souza disse:
26 de março de 2013 às 21:38
Está de parabéns pela forma clara e simples como ensina SQL, gostei e estou utilizando nas minhas aulas de banco de dados, gostei, continue assim, pois não sabe como está ajudando pessoas que se interessam pelo assunto, tenha uma ótima noite.
Muito obrigado Tâmara! A intenção é sempre ajudar! 🙂
Foi otima a sua explicação… parabens
VICENTE GARCIA M JUNIOR disse:
Caro Diego, não sou programador (de ofício), sou professor, formado em Física/UFG, mas tenho alguns softwares feitos em Delphi/Firebird que até me geram uma receita. Quando comecei a programar eu usava um banco de dados Access que se conecta facilmente ao Delphi, depois passei estudar o Firebird, agora então que a Enbarcadeiro criou o driver específico para a conexão com Firebird, estou achando lindo (rsrsrsr), mas tenho um amigo meu que tenta me convencer que o Postgres é muito superior ao Firebird. Você tem alguma opinião pra dar.
Olha só, a escolha de um SGBD vai muito de acordo com o projeto e com o gosto pessoal do desenvolvedor. Como é um aplicativo simples (corrija-me se estiver errado), creio que qualquer um deles vá satisfazer as suas necessidades, desde que você saiba manipular bem todos os recursos para ter um melhor desempenho.
Não querendo confundir a sua cabeça, mas já confundindo, já eu, prefiro o MySQL, pois sempre programei em PHP com ele. Na faculdade cheguei a ver o Oracle (para Administração de BD) e o Postgre (com Java). O Oracle no seu caso está fora de questão, por ser pago.
Se o Firebird está satisfazendo suas necessidades, tudo bem. Pra que mudar?
Esse post ajudou muito, a explicação ficou simples e clara, muito bom. Valeu, vou passar a acompanhar seus posts.
Opa Vicente, muito bom saber que estou ajudando alguém. E Muito obrigado por acompanhar meu blog. Qualquer dúvida, só comentar que eu irei responder dentro do possível. Grande abraço! 😉