You are on page 1of 16

SQL: Uma Linguagem de Consulta

Database Management Systems, R. Ramakrishnan
1
(tradução, autorizada, de Anna & Mario Nascimento)

Exemplos ilustrativos

❖ Considere, como sid b id day
R1
exemplos, as 22 101 1 0 / 1 0 /9 6
seguintes relações: 58 103 1 1 / 1 2 /9 6

sid sn am e ra tin g age
❖ Se a chave para a S1
22 d u s tin 7 4 5 .0
relacão de Reservas 31 lu b b e r 8 5 5 .5
(R1) contivesse 58 ru s ty 10 3 5 .0
somente os
atributos sid e bid sid sn am e r a tin g age
S2 28 yuppy 9 3 5 .0
como mudaria a
31 lu b b e r 8 5 5 .5
semântica? 44 guppy 5 3 5 .0
58 r u s ty 10 3 5 .0
Database Management Systems, R. Ramakrishnan
2
(tradução, autorizada, de Anna & Mario Nascimento)

1
Consulta Básica SQL
SELECT [DISTINCT] target-list
FROM relation-list
WHERE qualification
❖ relation-list Uma lista de relações (possivelmente com uma
range-variable depois de cada nome).
❖ target-list Uma lista de atributos das relações em relation-list
❖ qualification Comparações (entre atributos e/ou constantes)
combinadas usando AND, OR e NOT.
❖ DISTINCT é uma palavra chave opcional indicando que a
resposta não deve contem duplicações. Duplicações não são
eliminadas por default ! (porque ?)

Database Management Systems, R. Ramakrishnan
3
(tradução, autorizada, de Anna & Mario Nascimento)

Estratégia de Avaliação Conceitual

❖ A Semântica de uma consulta SQL é definida com
a seguintes estratégia de avaliação conceitual :
– Computar o produto-cartesiano da relation-list.
– Descartar tuplas se elas falharem qualifications.
– Deletar atributos que não estão na target-list.
– Se DISTINCT é especificada, eliminar duplicações.
❖ Esta estratégia é provavelmente a menos eficiente
para computar uma consulta! Um otimizador
achará mais estratégias eficientes para computar as
mesmas respostas.

Database Management Systems, R. Ramakrishnan
4
(tradução, autorizada, de Anna & Mario Nascimento)

2
Exemplos de Avaliação Conceitual

SELECT S.sname
FROM Sailors S, Reserves R
WHERE S.sid=R.sid AND R.bid=103

(sid) sname rating age (sid) bid day
22 dustin 7 45.0 22 101 10/10/96
22 dustin 7 45.0 58 103 11/12/96
31 lubber 8 55.5 22 101 10/10/96
31 lubber 8 55.5 58 103 11/12/96
58 rusty 10 35.0 22 101 10/10/96
58 rusty 10 35.0 58 103 11/12/96

Database Management Systems, R. Ramakrishnan
5
(tradução, autorizada, de Anna & Mario Nascimento)

Uma Nota sobre Range Variables
❖ Somente necessário se uma mesma relação
aparecer duas vezes na condição FROM.
A consulta anterior também pode ser escrita
como:
SELECT S.sname
FROM Sailors S, Reserves R Todavia usar
WHERE S.sid=R.sid AND bid=103 range variables
é uma boaidéia
OR SELECT sname (estilo)!
FROM Sailors, Reserves
WHERE Sailors.sid=Reserves.sid
AND bid=103

Database Management Systems, R. Ramakrishnan
6
(tradução, autorizada, de Anna & Mario Nascimento)

3
Que sailors reservaram pelo menos 1 barco?

SELECT S.sid
FROM Sailors S, Reserves R
WHERE S.sid=R.sid

❖ Adicionar DISTINCT para esta consulta, pode
fazer alguma diferença?
❖ Qual o efeito ao substituir S.sid por S.sname na
condição SELECT? Adicionar DISTINCT para esta
variante de consulta pode fazer diferença?

Database Management Systems, R. Ramakrishnan
7
(tradução, autorizada, de Anna & Mario Nascimento)

Expressões e Strings

SELECT S.age, age1=S.age-5, 2*S.age AS age2
FROM Sailors S
WHERE S.sname LIKE ‘B_%B’

❖ Ilustra o uso de expressões e padrões de strings:
Forma triplas (idade dos marinheiros e 2 atributos
definidos por expressões) para marinheiros cujo nomes
comecem e terminem com B e contenham 3 ou mais letras
❖ AS e = servem para nominar campos no resultado.
❖ LIKE é usado para strings. `_’ representa qualquer
letra e `%’ representa 0 ou mais letras.

Database Management Systems, R. Ramakrishnan
8
(tradução, autorizada, de Anna & Mario Nascimento)

4
Achar sid’s de sailors que reservaram um barco vermelho
ou um verde.
❖ UNION: Pode ser usado SELECT S.sid
para computar a união de FROM Sailors S, Boats B, Reserves R
dois conjuntos de tuplas WHERE S.sid=R.sid AND R.bid=B.bid
compatíveis (que são eles AND (B.color=‘red’ OR B.color=‘green’)

mesmos resultado de uma
consulta SQL).
SELECT S.sid
❖ Se substituirmos OR FROM Sailors S, Boats B, Reserves R
por AND na primeira WHERE S.sid=R.sid AND R.bid=B.bid
AND B.color=‘red’
versão , o que teremos?
UNION
❖ Também disponível: SELECT S.sid
EXCEPT (O que teremos se FROM Sailors S, Boats B, Reserves R
substituirmos UNION by WHERE S.sid=R.sid AND R.bid=B.bid
AND B.color=‘green’
EXCEPT?)
Database Management Systems, R. Ramakrishnan
9
(tradução, autorizada, de Anna & Mario Nascimento)

Achar Sid’s de marinheiros que tenham reservado um barco
vermelho e um verde.
SELECT S.sid
FROM Sailors S, Boats B1, Reserves R1,
❖ INTERSECT: Usado para Boats B2, Reserves R2
computar a intersecção WHERE S.sid=R1.sid AND R1.bid=B1.bid
AND S.sid=R2.sid AND R2.bid=B2.bid
de qualquer dois
AND (B1.color=‘red’ AND B2.color=‘green’)
conjuntos compatíveis
de tuplas. Key field!
❖ Incluido no padrão SELECT S.sid
SQL/92 mas não FROM Sailors S, Boats B, Reserves R
suportado por alguns WHERE S.sid=R.sid AND R.bid=B.bid
AND B.color=‘red’
sistemas.
INTERSECT
SELECT S.sid
FROM Sailors S, Boats B, Reserves R
WHERE S.sid=R.sid AND R.bid=B.bid
AND B.color=‘green’
Database Management Systems, R. Ramakrishnan
10
(tradução, autorizada, de Anna & Mario Nascimento)

5
Consultas Aninhadas
Ache nomes de marinheiros que reservaram barco # 103
SELECT S.sname
FROM Sailors S
WHERE S.sid IN (SELECT R.sid
FROM Reserves R
WHERE R.bid=103)

❖ Uma característica poderosa de SQL: Uma condição
WHERE pode conter uma consulta SQL! (De fato,
condições FROM e HAVING também podem)
❖ Para achar marinheiros que não tem reservas # 103,
use NOT IN.
Database Management Systems, R. Ramakrishnan
11
(tradução, autorizada, de Anna & Mario Nascimento)

Consultas aninhadas correlacionadas
Achar nomes de marinheiros que reservaram barco #103:
SELECT S.sname
FROM Sailors S
WHERE EXISTS (SELECT *
FROM Reserves R
WHERE R.bid=103 AND S.sid=R.sid)
❖ EXISTS é outra comparação, como IN.
❖ Se UNIQUE é usado, e * é substituído por R.bid, acha
marinheiros com pelo menos uma reserva para o barco #103.
(UNIQUE verifica tuplas duplicadas; Porque temos que
substituir * por R.bid?)
❖ Neste caso subconsultas tem que ser re-computadas por cada
tupla de marinheiros.
Database Management Systems, R. Ramakrishnan
12
(tradução, autorizada, de Anna & Mario Nascimento)

6
Ainda sobre operadores de conjuntos

❖ IN, EXISTS e UNIQUE pode-se também NOT, i.e., usar
NOT IN, NOT EXISTS e NOT UNIQUE.
❖ Também disponíveis: op ANY, op ALL, op IN, onde op
é >, <, =, etc.
❖ Achar marinheiros que cujo taxa é maior do que
algum marinheiro chamado Horatio:

SELECT *
FROM Sailors S
WHERE S.rating > ANY (SELECT S2.rating
FROM Sailors S2
WHERE S2.sname=‘Horatio’)
Database Management Systems, R. Ramakrishnan
13
(tradução, autorizada, de Anna & Mario Nascimento)

Escrevendo consultas INTERSECT usando IN
Encontre os sid’s que reservaram um barco vermelho e um barco verde :
SELECT S.sid
FROM Sailors S, Boats B, Reserves R
WHERE S.sid=R.sid AND R.bid=B.bid AND B.color=‘red’
AND S.sid IN (SELECT S2.sid
FROM Sailors S2, Boats B2, Reserves R2
WHERE S2.sid=R2.sid AND R2.bid=B2.bid
AND B2.color=‘green’)

❖ De modo similar, consultas EXCEPT podem ser
reescritas usando NOT IN.
❖ Para achar nomes substitua S.sid por S.sname na
condição SELECT. (Funciona com INTERSECT?)
Database Management Systems, R. Ramakrishnan
14
(tradução, autorizada, de Anna & Mario Nascimento)

7
Divisão em SQL

• Encontre os marinheiros que reservaram todos
barcos.

SELECT S.sname
FROM Sailors S
WHERE NOT EXISTS
((SELECT B.bid
FROM Boats B)
EXCEPT
(SELECT R.bid
FROM Reserves R
WHERE R.sid=S.sid))

Database Management Systems, R. Ramakrishnan
15
(tradução, autorizada, de Anna & Mario Nascimento)

Divisão em SQL

❖ Sem EXCEPT:

SELECT S.sname
(2) FROM Sailors S
WHERE NOT EXISTS (SELECT B.bid
FROM Boats B
WHERE NOT EXISTS (SELECT R.bid
FROM Reserves R
Sailors S such that ...
WHERE R.bid=B.bid
there is no boat B without ... AND R.sid=S.sid))

a Reserves tuple showing S reserved B

Database Management Systems, R. Ramakrishnan
16
(tradução, autorizada, de Anna & Mario Nascimento)

8
Operadores de Agregação
COUNT ( [DISTINCT] A)
❖ Extensão significante da álgebra SUM ( [DISTINCT] A)
relacional. AVG ( [DISTINCT] A)
MAX (A)
SELECT COUNT (*) MIN (A)
SELECT S.sname
FROM Sailors S single column
FROM Sailors S
SELECT AVG (S.age) WHERE S.rating= (SELECT MAX(S2.rating)
FROM Sailors S FROM Sailors S2)
WHERE S.rating=10

SELECT COUNT (DISTINCT S.rating) SELECT AVG ( DISTINCT S.age)
FROM Sailors S FROM Sailors S
WHERE S.sname=‘Bob’ WHERE S.rating=10
Database Management Systems, R. Ramakrishnan
17
(tradução, autorizada, de Anna & Mario Nascimento)

Achar nome e idade do(s) marinheiro(s)
mais velho(s)
SELECT S.sname, MAX (S.age)
❖ A primeira consulta é ilegal (?) FROM Sailors S

SELECT S.sname, S.age
FROM Sailors S
❖ A terceira consulta é
WHERE S.age =
equivalente a segunda consulta,
(SELECT MAX (S2.age)
e é considerada no padrão
FROM Sailors S2)
SQL/92, mas não é suportada
em alguns sistemas. SELECT S.sname, S.age
FROM Sailors S
WHERE (SELECT MAX (S2.age)
FROM Sailors S2)
= S.age
Database Management Systems, R. Ramakrishnan
18
(tradução, autorizada, de Anna & Mario Nascimento)

9
GROUP BY e HAVING

❖ Até agora, temos aplicados operadores de
agregação para todas as tuplas (qualificadas).
Algumas vezes, queremos aplicá-los para cada
um de diferentes grupo de tuplas.
❖ Ache a idade do mais jovem para cada nível de taxa.
– em geral, não sabemos quantos níveis de taxas existem,
e o quais são os valores destas taxas para estes níveis.
– Suponha que sabemos que estes valores de taxas vão
de 1 à 10, isso é razoavel ?
SELECT MIN (S.age)
For i = 1, 2, ... , 10: FROM Sailors S
WHERE S.rating = i
Database Management Systems, R. Ramakrishnan
19
(tradução, autorizada, de Anna & Mario Nascimento)

Consultas com GROUP BY e HAVING
SELECT [DISTINCT] target-list
FROM relation-list
WHERE qualification
GROUP BY grouping-list
HAVING group-qualification
❖ A target-list contem (i) atributos (ii) termos com
operações de agrega,cão (e.g., MIN (S.age)).
– Os atributos (i) tem que ser um sub conjunto de
grouping-list. Intuitivamente, cada resposta tupla
corresponde a um grupo, e estes atributos tem que ter um
valor simples por grupo. (Um grupo é um conjunto de
tuplas que tem o mesmo valor para todos os atributos em
grouping-list.)
Database Management Systems, R. Ramakrishnan
20
(tradução, autorizada, de Anna & Mario Nascimento)

10
Avaliação Conceitual

❖ O produto cartesiano da relation-list é computado,
tuplas que falham qualification são descartadas,
campos `desnecessários’ são deletados e as tuplas
restantes são divididas em grupos pelo valor dos
atributos em grouping-list.
❖ O group-qualification é então aplicado para eliminar
alguns grupos. Expressões em group-qualification tem
que ter um valor singular por grupo!
– Para todos os efeitos, um atributo no group-qualification
que não é um argumento de um operador agregado
também aparece no grouping-list.
Database Management Systems, R. Ramakrishnan
21
(tradução, autorizada, de Anna & Mario Nascimento)

Qual a menor idade do marinheiro com + de 18 anos ,
para cada grupo de taxa com 2 ou + tais mariheiros
sid sname rating age
SELECT S.rating, MIN (S.age)
FROM Sailors S
22 dustin 7 45.0
WHERE S.age >= 18
31 lubber 8 55.5
GROUP BY S.rating
71 zorba 10 16.0
HAVING COUNT (*) > 1 64 horatio 7 35.0
29 brutus 1 33.0
❖ Somente S.rating e S.age são 58 rusty 10 35.0
mencionados nas condições rating age
SELECT, GROUP BY or HAVING; 1 33.0
Outros atributos desnecessários’. 7 45.0 rating
❖ Segunda coluna de resultados 7 35.0 7 35.0
não é nominada. (Use AS para 8 55.5
nomina-la.) 10 35.0 Answer relation
Database Management Systems, R. Ramakrishnan
22
(tradução, autorizada, de Anna & Mario Nascimento)

11
Para cada barco vermelho, qual o o número de
reservas para este barco

SELECT B.bid, COUNT (*) AS scount
FROM Sailors S, Boats B, Reserves R
WHERE S.sid=R.sid AND R.bid=B.bid AND B.color=‘red’
GROUP BY B.bid

❖ Agrupando uma junção combinação de tres
relações.
❖ O que teremos se removermos B.color=‘red’
da condição WHERE e adicionamos uma
condição HAVING com esta condição?
❖ E se retirarmos Sailors e a condição
envolvendo S.sid?
Database Management Systems, R. Ramakrishnan
23
(tradução, autorizada, de Anna & Mario Nascimento)

Qual a idade do marinheiro mais jovem com idade >=
18, para cada grupo de taxa com 2 ou + marinheiros

SELECT S.rating, MIN (S.age)
FROM Sailors S
WHERE S.age >= 18
GROUP BY S.rating
HAVING 1 < (SELECT COUNT (*)
FROM Sailors S2
WHERE S.rating=S2.rating)

❖ A condição HAVING pode conter uma subconsulta.
❖ Compare com a consulta anterior

Database Management Systems, R. Ramakrishnan
24
(tradução, autorizada, de Anna & Mario Nascimento)

12
Encontre as taxas para as quais a idade média a
menor sobre todas as taxas.
❖ Operadores de agregação não podem ser
aninhados. ERRADO:
SELECT S.rating
FROM Sailors S
WHERE S.age = (SELECT MIN (AVG (S2.age)) FROM Sailors S2)
❖ Solução correta (in SQL/92):
SELECT Temp.rating, Temp.avgage
FROM (SELECT S.rating, AVG (S.age) AS avgage
FROM Sailors S
GROUP BY S.rating) AS Temp
WHERE Temp.avgage = (SELECT MIN (Temp.avgage)
FROM Temp)
Database Management Systems, R. Ramakrishnan
25
(tradução, autorizada, de Anna & Mario Nascimento)

Valores Nulos
❖ Os valores no campo de uma tupla são algumas vezes
desconhecidos ou não aplicaveis inapplicable
– SQL tem um valor nulo especial para estas situações.
❖ A presença de null complica muitos resultados. P.ex.:
– Operadores especiais para verificar se o valor é ou não nulo.
– rating>8 é verdadeiro ou falso quando rating é igual a nulo?
(Precisamos uma lógica de 3-valores).
– O significado das construção tem ser definido
cuidadosamente. (e.g., condição WHERE elimina linhas que
não são avaliadas como verdade.)
– Novos operadores (em particular, para outer joins)
possíveis/necessários
Database Management Systems, R. Ramakrishnan
26
(tradução, autorizada, de Anna & Mario Nascimento)

13
SQL Embutido

❖ Comandos SQL podem ser chamados de dentro de um
linguagem “hospedeira” (e.g., C ou COBOL)
– Comandos SQL podem se referir a host variables
(incluindo variáveis especiais usadas para retornar o status).
– Deve incluir um comando para connectar ao banco de dados
certo.
❖ Relações SQL são (multi-)conjuntos de registros,
limite do número de registros não limitados a priori.
Não há estruturas de dados similar em C.
– Para isso SQL suporta um mecanismo chamado cursor.

Database Management Systems, R. Ramakrishnan
27
(tradução, autorizada, de Anna & Mario Nascimento)

Cursores
❖ Podem ser declarados sobre uma relação ou consulta
❖ Pode-se abrir um cursor, e (repetidamente) capturar
tuplas, movendo o cursor.
– Pode usar uma clásula especial, chamada ORDER BY, em
consultas que são acessadas por cursor, para controlar a
ordem na qual as tuplas são retornadas.
◆ Campos em ORDER BY tem que aparecer também na condição
SELECT.
– A condição ORDER BY, que ordena a resposta tuplas, é
permitidas somente no contexto de um cursor.
❖ Pode-se também modificar/deletar tupla apontada
por um cursor.
Database Management Systems, R. Ramakrishnan
28
(tradução, autorizada, de Anna & Mario Nascimento)

14
Cursor com nomes de marinheiros que reservaram
um barco vermelho, em ordem alfabética .

EXEC SQL DECLARE sinfo CURSOR FOR
SELECT S.sname
FROM Sailors S, Boats B, Reserves R
WHERE S.sid=R.sid AND R.bid=B.bid AND B.color=‘red’
ORDER BY S.sname

❖ Note que é ilegal substituir S.sname por ,
digamos S.sid na consulta (Porque?)
❖ Podemos adicionar S.sid para a consulta SELECT
e substituir S.sname por S.sid na consulta in the
ORDER BY ?

Database Management Systems, R. Ramakrishnan
29
(tradução, autorizada, de Anna & Mario Nascimento)

“Embutindo” SQL em C: Um Exemplo.
char SQLSTATE[6];
EXEC SQL BEGIN DECLARE SECTION
char c_sname[20]; short c_minrating; float c_age;
EXEC SQL END DECLARE SECTION
c_minrating = random();
EXEC SQL DECLARE sinfo CURSOR FOR
SELECT S.sname, S.age FROM Sailors S
WHERE S.rating > :c_minrating
ORDER BY S.sname;
do {
EXEC SQL FETCH sinfo INTO :c_sname, :c_age;
printf(“%s is %d years old\n”, c_sname, c_age);
} while (SQLSTATE != ‘02000’);
EXEC SQL CLOSE sinfo;
Database Management Systems, R. Ramakrishnan
30
(tradução, autorizada, de Anna & Mario Nascimento)

15
Resumo
❖ Mais natural que antes, procedimentos de consulta de
linguagens.
❖ Relacionalmente completa; e significantemente mais
expressiva do que algebra relacional.
❖ Mesmo consultas que podem ser expressadas em AR podem
frequentemente ser expressadas mais naturalmente em SQL.
❖ Vários caminhos alternativos para escrever uma consulta;
otimizador deve procurar pelo plano de avaliação mais
eficiente.
– na prática, usuários precisam estar atentos como as consultas
podem ser otimizadas e avaliadas para melhores resultados.

Database Management Systems, R. Ramakrishnan
31
(tradução, autorizada, de Anna & Mario Nascimento)

16