Você está na página 1de 16

SQL: Uma Linguagem de Consulta

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

Exemplos ilustrativos

Considere, como exemplos, as seguintes relações:

Se a chave para a relacão de Reservas (R1) contivesse somente os atributos sid e bid como mudaria a semântica?

R1

S1

S2

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

sid

bid

day

22

101

10/10/96

58

103

11/12/96

sid

snam e

rating

age

22

dustin

7

45.0

31

lubber

8

55.5

58

rusty

10

35.0

sid

snam e

rating

age

28

yuppy

9

35.0

31

lubber

8

55.5

44

guppy

5

35.0

58

rusty

10

35.0

1

2

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 (tradução, autorizada, de Anna & Mario Nascimento)

3

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 (tradução, autorizada, de Anna & Mario Nascimento)

4

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 (tradução, autorizada, de Anna & Mario Nascimento)

 

Uma Nota sobre Range Variables

 

5

Somente necessário se uma mesma relação aparecer duas vezes na condição FROM. A consulta anterior também pode ser escrita como:

OR

SELECT S.sname

FROM

Sailors S, Reserves R

WHERE S.sid=R.sid AND bid=103

SELECT sname

FROM

WHERE Sailors.sid=Reserves.sid AND bid=103

Sailors, Reserves

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

Todavia usar range variables é uma boaidéia (estilo)!

6

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 (tradução, autorizada, de Anna & Mario Nascimento)

Expressões e Strings

7

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 (tradução, autorizada, de Anna & Mario Nascimento)

8

Achar sid’s de sailors que reservaram um barco vermelho ou um verde.

UNION: Pode ser usado para computar a união de dois conjuntos de tuplas compatíveis (que são eles mesmos resultado de uma consulta SQL).

Se substituirmos OR

por AND na primeira versão , o que teremos?

Também disponível:

EXCEPT (O que teremos se substituirmos UNION by

EXCEPT?)

SELECT S.sid

FROM Sailors S, Boats B, Reserves R WHERE S.sid=R.sid AND R.bid=B.bid AND (B.color=‘red’ OR B.color=‘green’)

SELECT S.sid

FROM Sailors S, Boats B, Reserves R WHERE S.sid=R.sid AND R.bid=B.bid AND B.color=‘red’

UNION

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 (tradução, autorizada, de Anna & Mario Nascimento)

9

Achar Sid’s de marinheiros que tenham reservado um barco vermelho e um verde.

INTERSECT: Usado para computar a intersecção de qualquer dois conjuntos compatíveis de tuplas.

Incluido no padrão SQL/92 mas não suportado por alguns sistemas.

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

SELECT S.sid

FROM Sailors S, Boats B1, Reserves R1, Boats B2, Reserves R2 WHERE S.sid=R1.sid AND R1.bid=B1.bid AND S.sid=R2.sid AND R2.bid=B2.bid AND (B1.color=‘red’ AND B2.color=‘green’)

Key field! D (B1.color=‘red’ A N D B2.color=‘green’) SELECT S.sid F R O M Sailors S, Boats B,

SELECT S.sid

FROM Sailors S, Boats B, Reserves R WHERE S.sid=R.sid AND R.bid=B.bid AND B.color=‘red’

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’

10

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 (tradução, autorizada, de Anna & Mario Nascimento)

11

Consultas aninhadas correlacionadas

Achar nomes de marinheiros que reservaram barco #103:

SELECT S.sname FROM Sailors S

WHERE

#103: S E L E C T S.sname FROM Sailors S WHERE EXISTS ( S E

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 (tradução, autorizada, de Anna & Mario Nascimento)

12

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:

é >, <, =, etc.

op ANY, op ALL, op IN, onde op

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 (tradução, autorizada, de Anna & Mario Nascimento)

13

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 (tradução, autorizada, de Anna & Mario Nascimento)

14

Divisão em SQL • Encontre os marinheiros que reservaram todos barcos. SELECT S.sname FROM Sailors
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
(tradução, autorizada, de Anna & Mario Nascimento)
15
Divisão em SQL

(2)

Sem EXCEPT:

SELECT S.sname FROM Sailors S

WHERE NOT EXISTS (SELECT B.bid

FROM Boats B

WHERE NOT EXISTS (SELECT R.bid

Sailors S such that

there is no boat B without

a Reserves tuple showing S reserved B

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

FROM Reserves R WHERE R.bid=B.bid AND R.sid=S.sid))

16

Operadores de Agregação

Extensão significante da álgebra relacional.

SELECT COUNT (*)

COUNT ( [DISTINCT] A) SUM ( [DISTINCT] A) AVG ( [DISTINCT] A)

MAX (A)

MIN (A)

FROM Sailors S

SELECT AVG (S.age)

FROM Sailors S WHERE S.rating=10

SELECT S.sname FROM Sailors S

WHERE S.rating= (SELECT MAX(S2.rating)

a t i n g = ( S E L E C T MAX (S2.rating) single

single column

FROM Sailors S2)

SELECT COUNT (DISTINCT S.rating)

FROM Sailors S WHERE S.sname=‘Bob’

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

SELECT AVG ( DISTINCT S.age)

FROM Sailors S WHERE S.rating=10

17

Achar nome e idade do(s) marinheiro(s) mais velho(s)

A primeira consulta é ilegal (?)

SELECT S.sname, MAX (S.age) FROM Sailors S

A terceira consulta é equivalente a segunda consulta, e é considerada no padrão SQL/92, mas não é suportada em alguns sistemas.

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

SELECT S.sname, S.age FROM Sailors S WHERE S.age = (SELECT MAX (S2.age) FROM Sailors S2)

SELECT S.sname, S.age FROM Sailors S

WHERE (SELECT MAX (S2.age)

FROM Sailors S2) = S.age

18

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 ?

For i = 1, 2,

, 10:

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

SELECT MIN (S.age) FROM Sailors S WHERE S.rating = i

19

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 (tradução, autorizada, de Anna & Mario Nascimento)

20

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 (tradução, autorizada, de Anna & Mario Nascimento)

21

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 WHERE S.age >= 18
sid
sname
rating
age
SELECT S.rating, MIN (S.age)
FROM Sailors S
WHERE S.age >= 18
GROUP BY S.rating
22
dustin
7
45.0
31
lubber
8
55.5
71
zorba
10
16.0
64
horatio
7
35.0
HAVING COUNT (*) > 1
29
brutus
1
33.0
58
rusty
10
35.0

Somente S.rating e S.age são mencionados nas condições

SELECT, GROUP BY or HAVING;

Outros atributos desnecessários’.

Segunda coluna de resultados não é nominada. (Use AS para nomina-la.)

rating

age

1

7

7

8

10

33.0

45.0

35.0

55.5

35.0

rating 7 35.0 Answer relation
rating
7 35.0
Answer relation

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

22

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 (tradução, autorizada, de Anna & Mario Nascimento)

23

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 (tradução, autorizada, de Anna & Mario Nascimento)

24

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 (tradução, autorizada, de Anna & Mario Nascimento)

25

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 (tradução, autorizada, de Anna & Mario Nascimento)

26

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 (tradução, autorizada, de Anna & Mario Nascimento)

27

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 (tradução, autorizada, de Anna & Mario Nascimento)

28

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 (tradução, autorizada, de Anna & Mario Nascimento)

29

“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 (tradução, autorizada, de Anna & Mario Nascimento)

30

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 (tradução, autorizada, de Anna & Mario Nascimento)

31