SdI05 - Linguagem SQL
SdI05 - Linguagem SQL
1 3 5
Estudo da Normalização
Modelo Relacional ❑ do inglês DML - “Data Manipulation Language” ❑ 1992: Norma SQL-92 ou SQL2 (ISO/IEC 9075:1992)
❑ 1999: Norma SQL:1999 ou SQL3
Normalização do Modelo Relacional ❑ Permite: ◼ Added regular expression matching, recursive queries, triggers, support for procedural
and control-of-flow statements, non-scalar types, and some object-oriented features.
◼ aceder à informação armazenada na base de dados ❑ 2003: Norma SQL:2003
Modelo Relacional Normalizado ◼ Introduced XML-related features, window functions, standardized sequences, and columns with
Estudo da LDD -SQL ◼ inserir nova informação na base de dados auto-generated values
◼ eliminar informação na base de dados ❑ 2006: Norma SQL:2006
Construção do modelo físico para um SGBD ◼ ISO/IEC 9075-14:2006 defines ways in which SQL can be used in conjunction with XML. It
◼ alterar informação na base de dados defines ways of importing and storing XML data in an SQL database, manipulating it within the
Estudo da álgebra relacional database and publishing both XML and conventional SQL-data in XML form. In addition, it
Desenho físico e implementação provides facilities that permit applications to integrate into their SQL code the use of XQuery, to
concurrently access ordinary SQL-data and XML documents.
Estudo da LMD -SQL BD - 07 de Dados 2 4 6
Utilização da Bases
2 4 6
1
SQL - Alguns comandos principais Definição do Esquema da Base de Dados Tipos de Dados
◼ Interrogação ◼ Comandos SQL pertencentes à Linguagem de Definição de Dados
◼ No caso do MySQL:
❑ SELECT. Usado para interrogar a BD. (LDD):
❑ Binários: BIT[(n)]
❑ CREATE, para criar uma tabela
◼ Manipulação de Dados ❑ Caracter: CHAR[(n)], VARCHAR[(n)], ENUM, TEXT
❑ ALTER, para alterar uma tabela existente
❑ INSERT, UPDATE, DELETE. Usados para inserir novos registos em ❑ Data e Hora: DATE, DATETIME, TIME, YEAR, TIMESTAMP
❑ DROP, para eliminar uma tabela a existente
tabelas, alterar ou eliminar registos já existentes. ❑ Numérico exacto: DECIMAL[(p[,s])], NUMERIC [(p[,s])],
❑ Numérico aproximado: FLOAT[(n, d)], DOUBLE[(m, d)]
◼ Definição de Dados ◼ Uma tabela pode ser criada em qualquer momento de uma sessão SQL
❑ Inteiro: BIGINT, INT, MEDIUMINT, SMALLINT, TINYINT
❑ CREATE, ALTER, DROP. Usados para criar, alterar ou eliminar ◼ A estrutura de uma tabela pode ser alterada em qualquer momento de
qualquer estrutura de dados (tabelas, vistas e índices). uma sessão SQL
◼ Toda a informação eliminada não pode ser recuperada
◼ Controlo de Transações
❑ COMMIT, SAVEPOINT, ROLLBACK. Usados para controlar
explicitamente as transacções. ◼ Uma tabela não tem qualquer dimensão predeterminada
◼ Autorizações e Segurança
❑ GRANT, REVOKE. Usados para atribuir ou retirar direitos de acesso. MEDIUMINT - 3 bytes
7 9 11
7 9 11
❑
DECIMAL, NUMERIC
FLOAT, REAL, DOUBLE PRECISION
◼ Algumas características de tipos de dados (no caso de SQL Server):
❑ Para os tipos de dados VAR...(n) apenas é alocado o espaço necessário
❑ INTEGER, SMALLINT para guardar o dado, até ao máximo definido (n), que pode ter o valor de
max (231-1 bytes/caracteres ).
◼ No caso do SQL Server: ❑ Para o correspondente tipo sem o prefixo VAR, é alocado todo o espaço
❑ Binários: BINARY[(n)], VARBINARY[(n)] definido (n), independentemente da dimensão efectiva do dado.
DDL – Linguagem de Definição de Dados ❑ Caracter: CHAR[(n)], VARCHAR[(n)] ◼ Pelo facto de ocupar um espaço fixo, o acesso ao tipo VAR... pode ser mais rápido
do que ao correspondente tipo sem o prefixo VAR
❑ Data e Hora: DATETIME, SMALLDATETIME (ao milissegundo, ao minuto)
◼ É de utilizar o tipo VAR quando se prevê, nessa coluna, existência de valores
❑ Numérico exacto: DECIMAL[(p[,s])], NUMERIC[(p[,s])] (numeric = decimal) nulos ou grandes variações na dimensão dos dados
❑ Numérico aproximado: FLOAT[(n)], REAL (n bits of mantissa (1-53), default 53, ❑ BINARY(n), n grupos de 2 dígitos hexadecimais, para guardar dados binários
real = float(24)
❑ DATETIME, data e hora (8bytes), com resolução ao milissegundo (3.33 ms) *
❑ Inteiro: BIGINT, INT, SMALLINT, TINYINT (respectivamente 8, 4, 2 e1 bytes)
❑ SMALLDATETIME, data e hora (4bytes), com resolução ao minuto *
❑ Monetário: MONEY, SMALLMONEY (respectivamente 8 e 4 bytes) * desde 1/1/1900
8 10 12
8 10 12
2
Tipos de Dados (cont. 1) Criação de uma tabela - restrições Criação de uma tabela – exemplos
◼ Algumas características de tipos de dados (no caso de SQL Server): ◼ restrição_coluna (aplica-se apenas a uma coluna) ◼ Definição de uma tabela com chave estrangeira composta:
CREATE TABLE ENTREGA (
❑ DECIMAL e NUMERIC são idênticos e existem ambos por razões de numEntrega int,
compatibilidade. ◼ restrição_tabela (aplica-se a uma ou mais colunas)
dataEntrega datetime NOT NULL,
❑ DECIMAL[(p[,s])] - o parâmetro “p” (precision) indica o número máximo total ◼ Definição de uma restrição: numFactura int NOT NULL,
de dígitos; o parâmetro “s” (scale) indica o número máximo de dígitos à CONSTRAINT nome_restrição numLinha int NOT NULL,
direita do ponto decimal. [PRIMARY KEY | UNIQUE] ( coluna, … ) | CONSTRAINT pk_ENTREGA PRIMARY KEY ( numEntrega ),
◼ No SQL Server precision pode ir de 1 a 38, com valor por omissão de 18. Scale [FOREIGN KEY ( coluna, … ) {REFERENCES tabela [( coluna, … )] CONSTRAINT fk1_ENTREGA FOREIGN KEY ( numFactura, numLinha )
por ir até 0 a precision, sendo o valor por omissão de 0. [ON DELETE {NO ACTION | CASCADE | SET DEFAULT | SET NULL} ] | REFERENCES FACTURA ( numFactura, numLinha )
◼ Espaço ocupado: varia em função de precision/p, sendo 5 se p [1 – 9], 9 se p [ON UPDATE {NO ACTION | CASCADE | SET DEFAULT | SET NULL} ] } | ON DELETE CASCADE
[10-19], 13 se p [20-28] e 17 se p [29-38]. [CHECK ( condição )] )
❑ FLOAT[(n)] – n indica o número de bits para guardar a mantissa. ❑ ON DELETE/UPDATE: NOACTION, CASCADE, SET DEFAULT, SET NULL Considere-se que cada item de factura pode ser entregue separadamente.
◼ No SQL server, o n pode variar entre 1 e 53, sendo 53 o seu valor por omissão, Não será o caso normal.
mas o seu valor é tido como 24 se for inferior ou igual a 24, e 53 se for superior a Remoção de um tuplo que tenha tuplos a referencia-lo, por intermédio de uma chave
estrangeiras, resulta em:
24. O espaço ocupado é de 4 bytes para n = 24 e 8 bytes para n = 53, tendo ON DELETE CASCADE indica que,
ON DELETE NOACTION→ a acção de DELETE não é realizada ❑
respectivamente uma precisão de 7 e 15 dígitos.
ON DELETE CASCADE→ na remoção desses tuplos ◼ a remoção de uma linha da tabela FACTURA ,
◼ O tipo REAL, corresponde a FLOAT(24) ON DELETE SET DEFAULT→ na colocação das referências com o valor por omissão ◼ implica a remoção das linhas da tabela ENTREGA que lhe estiverem associadas
ON DELETE SET NULL → na colocar dessas referências a NULL
13 15 17
13 15 17
Criação de uma tabela Criação de uma tabela – exemplos Criação de uma tabela – exemplos
◼ Definição de uma tabela com uma regra de verificação (CHECK):
◼ Comando CREATE ◼ Definição de uma tabela com uma chave primária, uma chave CREATE TABLE ENCOMENDA (
CREATE TABLE nome_tabela ( candidata (alternativa) e restrição de valor NULL por CHECK: numEnc int CONSTRAINT pk_ENCOMENDA PRIMARY KEY,
nome_coluna tipo [restrição_coluna], ... CREATE TABLE ALUNO ( dataEnc datetime NOT NULL,
[restrição_tabela, …] numAluno int CONSTRAINT pk_ALUNO PRIMARY KEY, codCliente int NOT NULL CONSTRAINT fk1_ENCOMENDA
numBI char(8) NOT NULL CONSTRAINT ak1_ALUNO UNIQUE, FOREIGN KEY (codCliente) REFERENCES CLIENTE (codCliente),
[AS SELECT comando]
dataEntrega datetime,
) nome varchar(100), CONSTRAINT ck1_ENCOMENDA CHECK ( dataEntrega > dataEnc )
CONSTRAINT ck1_ALUNO CHECK ( nome IS NOT NULL ) )
)
◼ Exemplo de criar uma tabela com algumas colunas ◼ Definição de uma tabela com valores seleccionados de outra tabela:
CREATE TABLE ITEMFACTURA ( ◼ Definição de uma tabela com chave primária composta: CREATE TABLE EMPREGADO_AUX (
numFactura int, CREATE TABLE FACTURA ( (codigoEmpregado, nomeEmpregado, codigoCategoria)
numLinha int, numFactura int, AS SELECT codEmp, nome, codCat FROM EMPREGADO
descricaoProd varchar(30), numLinha int, )
quantidade int NOT NULL DEFAULT ‘1’ produto varchar(50) not null, 1. Cria a tabela Empregado_aux com as colunas codigoEmpregado, nomeEmpregado e
) quantidade int not null, codigoCategoria, que irão ter domínios idênticos respectivamente às colunas codEmp,
CONSTRAINT pk_FACTURA PRIMARY KEY ( numFactura, numLinha ) nome e codCat da tabela Empregado.
) 2. A tabela Empregado_aux é preenchida com o resultado do select, ou seja com todos os
NOT NULL, indica que a coluna não pode receber o valor NULL empregados.
DEFAULT ‘1’, indica que o valor por omissão é 1
No SQL Server: select codDep, nomeDep into departamento_aux from departamento where ...;
14 16 18
14 16 18
3
Alterações a uma tabela Alterações a uma tabela (cont. 2)
◼ Comando ALTER
◼ Exemplos de alterações:
Manipulação de dados
ALTER TABLE nome_tabela
[ ADD novas colunas | novas restrições_coluna ]
❑ Eliminar uma coluna:
[ MODIFY definição das colunas ]
19 21 23
19 21 23
20 22 24
20 22 24
4
Inserção de linhas numa tabela Inserção de linhas numa tabela (cont.) Remoção de linhas numa tabela
◼ Inserção directa de dados
◼ Inserção de dados provenientes de uma tabela ◼ Pretende-se remover os empregados do departamento 222
◼ Pretende-se registar a existência do departamento de Marketing,
localizado em Lisboa e com código 4 ◼ Pretende-se: DELETE FROM EMPREGADO
INSERT INTO DEPARTAMENTO ( codDep, nome, localizacao ) ❑ copiar para a tabela com informação histórica dos empregados, todos os WHERE codDep = 222
VALUES( 4, 'Marketing', 'Lisboa’ ) empregados dos departamentos de Lisboa.
❑ o Esquema de Relação que irá conter a informação histórica dos
◼ Características do comando INSERT (aplicado deste modo): empregados é: HISTORICO_EMPREGADO( codEmp, nome ) ◼ Pretende-se remover toda a informação relativa ao histórico dos
❑ apenas se pode inserir uma linha de cada vez * empregados
❑ pode-se omitir a lista de nomes de colunas, desde que se respeite a ordem INSERT INTO HISTORICO_EMPREGADO( codEmp, nome ) DELETE FROM HISTORICO_EMPREGADO
das colunas definidas na tabela e não se omita nenhum valor SELECT codEmp, E.nome
❑ pode-se inserir uma linha apenas com algumas das colunas da tabela, FROM EMPREGADO AS E INNER JOIN DEPARTAMENTO AS D
ON (E.codDep = D.codDep ) ◼ Características do comando DELETE:
ficando os campos omitidos com valores nulos
WHERE localizacao = ‘Lisboa’ ❑ se a cláusula WHERE for omitida, todas as linhas da tabela são removidas
❑ É boa política indicar os nomes das colunas, pois fica-se com independência
face a alterações na definição da tabela ◼ Características do comando INSERT (aplicado deste modo):
Multirow inserts, since SQL-92 (DB2, MySQL, H2, PostgreSQL) ❑ o número de colunas na lista da cláusula SELECT tem que ser igual ao
INSERT INTO table (column1, [column2, ... ])
VALUES (value1a, [value1b, ...]) [, (value2a, [value2b, ...]) ] * número de colunas referidas no comando INSERT e os domínios de colunas
Exemplo: correspondentes têm que ser compatíveis
INSERT INTO phone_book VALUES ('John Doe', '555-1212'), ('Peter Doe', '555-2323');
25 27 29
25 27 29
26 28 30
26 28 30
5
Vistas (Views) da Base de Dados Criação de uma Vista – View Tratamento das Vistas pelo SGBD
◼ Usando a terminologia SQL, uma Vista (normalmente referida como ◼ Comando CREATE VIEW ◼ O comando CREATE VIEW não origina a execução do comando
View) consiste numa única tabela construída a partir de: CREATE VIEW nome_vista SELECT a ele associado.
❑ outras tabelas ou [ (nome_coluna_1, nome_coluna_2, ...) ]
◼ O comando CREATE VIEW apenas origina o armazenamento da
❑ outras Vistas anteriormente definidas. AS SELECT comando [WITH CHECK OPTION] definição da vista (directiva SELECT) no dicionário de dados.
◼ Características de uma Vista (View): ◼ “nome_coluna_i”: ◼ Ao aceder aos dados através de uma vista, o sistema:
❑ Uma Vista (View) não tem dados próprios. ❑ nome da coluna usado na vista. Se não for especificado é assumido o ❑ extrai do dicionário de dados, a definição da vista;
❑ Os dados de uma Vista (View) são manipulados na(s) tabela(s) base que mesmo nome das colunas definidas na cláusula SELECT.
❑ verifica as permissões de acesso à vista;
servem de suporte a essa Vista.
◼ “AS SELECT comando” - consiste na directiva SELECT que define a ❑ converte a operação sobre a vista numa operação equivalente na tabela ou
❑ Uma Vista (View) é armazenada como um comando SELECT.
vista, podendo usar mais do que uma tabela e outras vistas. Esta tabelas que servem de base à vista.
◼ Uma Vista (View) é uma tabela virtual, isto é, não tem existência física directiva tem algumas limitações:
embora apareça ao utilizador como se o tivesse, pelo que: ❑ não pode incluir as cláusulas ORDER BY
❑ origina algumas limitações às operações de actualização (update); ❑ não pode incluir a instrução INTO
❑ não origina limitações às operações de interrogação (select). ❑ não pode referenciar uma tabela temporária.
31 33 35
31 33 35
Tipos de Vistas (Views) e sua utilidade Criação de uma Vista - View (Cont.) Interrogação a uma Vista - View
◼ Tipos de Vistas (Views) ◼ Considere-se o seguinte Esquema Relacional: ◼ Pretende-se, utilizando a vista INFORMACAO_DEPARTAMENTO,
❑ Vistas simples: ❑ DEPARTAMENTO ( nome, localizacao ) saber:
◼ construídas com base numa única tabela; ❑ EMPREGADO ( cod, nome, salario, nomeDep ) ❑ Para o departamento de Informática, quantos empregados existem e qual o
◼ não contêm funções nem grupos de dados. montante total de salários.
◼ Pretende-se criar uma vista que permita saber:
❑ Vistas complexas:
◼ construídas com base em várias tabela; ❑ Para cada departamento quantos empregados existem e qual o montante SELECT numEmpregados, totalSalarios
total de salários. FROM INFORMACAO_DEPARTAMENTO
◼ contêm funções ou grupos de dados.
WHERE nomeDepartamento = ‘Informática’
CREATE VIEW INFORMACAO_DEPARTAMENTO
◼ Utilidade das Vistas (Views): (nomeDepartamento, numEmpregados, totalSalarios)
❑ restringir o acesso à Base de Dados mostrando apenas parte dos dados; AS SELECT D.nome, COUNT(*), SUM(salario) ◼ A vista não é concretizada no momento em que é criada, mas sempre
simplificar a consulta dos dados, substituindo consultas elaboradas FROM DEPARTAMENTO AS D INNER JOIN EMPREGADO AS E
❑
ON ( D.nome = E.nomeDep )
que é especificada uma interrogação sobre essa vista, mantendo-se
envolvendo várias tabelas, por fáceis consultas sobre a Vista; assim sempre actualizada.
GROUP BY D.nome
❑ permitir que os mesmos dados sejam visualizados de diferentes maneiras
por diferentes utilizadores; ◼ Esta vista é complexa: várias tabelas, funções e agregação de dados ◼ As alterações das tabelas originais reflectem-se nas diversas vistas
❑ reduzir a possibilidade de incoerências (opção WITH CHECK OPTION - dessas tabelas.
alteração de dados através da Vista de acordo com a sua definição).
32 34 36
32 34 36
6
Remoção de uma Vista - View Actualização de dados através de uma Vista (cont. 1) Verificação de Integridade em Vistas
◼ Comando DROP ◼ O comando de DELETE não é permitido se a vista incluir: ◼ Pretende-se criar uma vista que permita saber:
DROP VIEW nome_vista ❑ condições de junção (join); ❑ Quais os empregados que têm um salário inferior a 250000.
❑ funções de agrupamento; ❑ Também se pretende que qualquer acção de alteração sobre essa vista
◼ Exemplo de remoção da vista INFORMACAO_DEPARTAMENTO ❑ o comando DISTINCT; apenas afecte os empregados cujo salário seja inferior a 250000.
DROP VIEW INFORMACAO_DEPARTAMENTO ❑ sub-interrogações correlacionadas.
CREATE VIEW VISTA_EMPREGADO
◼ O comando de UPDATE não é permitido se a vista incluir: AS SELECT cod, nome
◼ Algumas características da acção de remoção de uma vista: ❑ qualquer das limitações do comando DELETE; FROM EMPREGADO
❑ a remoção de uma vista não tem qualquer influência nos dados das tabelas ❑ colunas definidas por expressões (tal como, salarioAno = 14 * salario). WHERE salario < 250000
que lhe serviam de base. WITH CHECK OPTION
❑ se existirem outras vistas que dependam da vista removida, essas vistas ◼ O comando de INSERT não é permitido se a vista incluir:
◼ Devido ao Check Option as instruções de INSERT e UPDATE sobre a
deixam de ser válidas. ❑ qualquer das limitações do comando UPDATE;
vista têm que verificar as condições definidas na cláusula WHERE.
❑ uma vista só pode ser removida por um utilizador com permissões para ❑ colunas com possibilidade de ter valores NOT NULL que não tenham valores
❑ a operação será rejeitada no caso dos dados não verificarem essas
efectuar essa operação ou pelo administrador da Base de Dados. de omissão nas tabelas base e que não estejam incluídas na vista através da
condições.
qual se pretende inserir novas colunas.
37 39 41
37 39 41
Actualização de dados através de uma Vista Actualização de dados através de uma Vista (cont. 2)
◼ Se a vista for definida sobre: ◼ Os comandos de INSERT e UPDATE são permitidos em vistas
uma única tabela e contendo várias tabelas base se:
Interrogação de dados
❑
❑ sem funções de agregação de dados, ❑ o comando afectar apenas uma das tabelas que serve de base à vista;
❑ é uma operação simples que se traduz na actualização da tabela que lhe ❑ no entanto, não é permitido num mesmo comando alterar mais do que uma
◼
serve de base.
38 40 42
38 40 42
7
Interrogação à Base de Dados Projecção (select distinct) Composição de operações de Restrição e Projecção
EMPREGADO
codEmp nomeEmp dataAdmissao codCat codDept codEmpChefe
EMPREGADO 1 António Abreu 01-Jan-99 1 1 1
◼ Começando pela interrogação da Base de Dados, a sintaxe geral de codEmp nomeEmp dataAdmissao codCat codDept codEmpChefe 2 Bernardo Bento 01-Jan-99 1 2 1
1 António Abreu 01-Jan-99 1 1 1 3 Carlos Castro 01-Jan-99 3 3 1
uma questão SQL é a seguinte: 2 Bernardo Bento 01-Jan-99 1 2 1 4 Manuel Matos 7-Feb-90 3 2 2
SELECT [DISTINCT] <colunas> | * 3 Carlos Castro 01-Jan-99 3 3 1
4 Manuel Matos 7-Feb-90 3 2 2 ◼ Qual o nome e data de admissão dos empregados da categoria com
FROM <tabelas> código 3, admitidos antes do dia 1 de Janeiro de 1998 ?
[WHERE <condição>] ◼ Quais as datas de admissão e código de categoria dos ❑ nomeEmp, dataAdmissao ( codCat = 3 dataAdmissao < ‘01/01/1998’ ( EMPREGADO ) )
◼ Onde
empregados?
❑ dataAdmissao, codCat (EMPREGADO) SELECT DISTINCT nomeEmp, dataAdmissao nomeEmp dataAdmissao
❑ <colunas> especifica a lista de atributos cujos valores interessa conhecer FROM EMPREGADO Manuel Matos 7-Feb-90
dataAdmissao codCat
❑ <tabelas> especifica quais as tabelas envolvidas no processamento da
SELECT dataAdmissao, codCat 01-Jan-99 1 WHERE codCat = 3 AND dataAdmissao < ‘01/01/1998’
interrogação 01-Jan-99 1
FROM EMPREGADO 01-Jan-99 3
❑ <condição> traduz a expressão lógica que define a condição a verificar 7-Feb-90 3 ◼ Quais os nomes dos empregados que são chefes deles próprios?
❑ DISTINCT é aplicado a todas as colunas especificadas na cláusula SELECT ❑ nomeEmp ( codEmp = codEmpChefe ( EMPREGADO ) )
e elimina as repetições existentes ◼ DISTINCT - garante que não existem tuplos duplicados
❑ O símbolo * é utilizado quando se pretendem seleccionar todos os atributos SELECT DISTINCT nomeEmp
dataAdmissao codCat
da tabela especificada na cláusula FROM SELECT DISTINCT dataAdmissao, codCat 01-Jan-99 1
FROM EMPREGADO nomeEmp
FROM EMPREGADO 01-Jan-99 3 WHERE codEmp = codEmpChefe António Abreu
7-Feb-90 3
43 45 47
43 45 47
44 46 48
8
União (cont.) Produto Cartesiano e Restrição Ambiguidade na identificação dos Atributos
◼ A fim de fazer os convites para a festa de Natal em Lisboa, pretende-se ◼ O Produto Cartesiano, por si só, tem uma utilidade limitada pois ◼ Pode existir ambiguidade nas operações quando,
a lista com todos os nome e telefones de todos os empregados e
os registos são associados sem qualquer critério ❑ dois (ou mais) Atributos têm o mesmo nome em Relações diferentes
somente dos fornecedores de Lisboa, existentes nas tabelas
EMPREGADO e FORNECEDOR ◼ Pode ter mais interesse saber por exemplo, ◼ A ambiguidade é eliminada com a qualificação do Atributo,
EMPREGADO
codEmp nome telefone ❑ Qual o material fornecido por cada fornecedor ? ❑ colocando o nome da Relação como prefixo do nome do Atributo
1 António Abreu 212555666
SELECT nome, telefone 2 Bernardo Bento 212777888 ❑ codMaterial = numeroMaterial (FORNECE MATERIAL) ◼ Considere-se o seguinte Esquema Relacional
FROM EMPREGADO 3 Carlos Castro 212555444
4 Manuel Matos 212333111 ❑ FORNECE( codFornecedor, codMaterial )
UNION ALL Fornecedor SELECT * ❑ MATERIAL( codMaterial , nome )
SELECT nome, telefone nomeForn telefone localidade
FROM FORNECE, MATERIAL
Continentix 222111333 Lisboa ◼ Qual o código e nome dos materiais fornecidos por cada fornecedor?
FROM FORNECEDOR Jumbix 222222111 Lisboa WHERE codMaterial = numeroMaterial ❑ 3, 4, 1 ( FORNECE MATERIAL )
WHERE localidade = ‘Lisboa’ Feira Novix 222333444 Porto 2=1
Pingo Docix 222555111 Porto ◼ O interesse prático da aplicação da operação de Restrição sobre
nome telefone
Continentix 222111333
a Relação resultante de um Produto Cartesiano, SELECT FORNECE.codMaterial, nome, codFornecedor
Jumbix 222222111 ❑ levou à definição da operação de Junção (Join) FROM FORNECE, MATERIAL
António Abreu 212555666
Bernardo Bento 212777888 WHERE FORNECE.codMaterial = MATERIAL.codMaterial
Carlos Castro 212555444
Manuel Matos 212333111
49 51 53
49 51 53
50 52 54
9
Junção, Projecção e Restrição Junção, Projecção e Restrição (cont.) Junções Múltiplas
FORNECE MATERIAL
codFornecedor
1
codMaterial
001
numeroMaterial nome ◼ Outra solução para a questão anterior poderia ser: ◼ Considere-se o seguinte Esquema Relacional
2
2
001
002
001
002
Parafuso
Roda Dentada
❑ nome (( codFornecedor = 1 (FORNECE)) codMaterial = numeroMaterial MATERIAL) ) ❑ CATEGORIA( codCat, nomeCat, salarioBase )
3 002
❑ DEPARTAMENTO( codDep, nomeDep, localizacao )
SELECT M.nome ❑ EMPREGADO( cod_Emp, nomeEmp, codCat, codDep, codEmpChefe )
◼ Qual o nome dos materiais fornecidos pelo fornecedor de código 1 ? FROM ( SELECT *
❑ nome ( codFornecedor = 1 (FORNECE codMaterial = numeroMaterial MATERIAL )) FROM FORNECE ◼ Para cada categoria, pretende-se saber qual o nome dos empregados,
WHERE codFornecedor = 1 ) AS F salário base e respectivo nome do departamento
SELECT M.nome AS nomeDoMaterial INNER JOIN ❑ 2, 5, 3, 10 ((CATEGORIA 1=3 EMPREGADO) 7=1 DEPARTAMENTO)
FROM FORNECE AS F INNER JOIN MATERIAL AS M MATERIAL AS M
nomeDoMaterial
ON ( F.codMaterial = M.numeroMaterial ) Parafuso ON ( F.codMaterial = M.numeroMaterial ) SELECT C.nomeCat, E.nomeEmp, C.salarioBase, D.nomeDep
WHERE F.codFornecedor = 1 FROM
◼ Nesta solução a operação de Restrição é efectuada antes da Junção ( CATEGORIA AS C INNER JOIN EMPREGADO AS E
o conjunto de tuplos a considerar na Junção é menor do que na solução ON ( C.codCat = E.codCat ) ) INNER JOIN DEPARTAMENTO AS D
◼ Notar que também às colunas se podem atribuir pseudónimos ❑
ON ( E.codDep = D.codDep )
◼ Por vezes os pseudónimos são usados para melhorar a legibilidade anterior
❑ contudo os SGBD já fazem estas optimizações de forma automática
55 57 59
55 57 59
56 58 60
10
Natural join Junção Externa (cont.)
◼ Uma Junção Natural (Natural Join) compara todas as colunas, que ◼ Se apenas estiverem disponíveis as operação de Junção Externa à
têm o mesmo nome, nas duas tabelas
Funções de agregação
Esquerda e à Direita, a interrogação anterior pode ser escrita,
◼ A tabela resultante apenas contém uma coluna por cada par de
❑ (EMPREGADO 3<1CATEGORIA) (EMPREGADO 3<1CATEGORIA)
colunas comparadas
SELECT *
◼ Expressão relacional de uma junção natural:
❑ CATEGORIA EMPREGADO FROM EMPREGADO EMP LEFT OUTER JOIN CATEGORIA CAT
ON ( EMP.codCat < CAT.codCat )
◼ Comando SQL com um natural join: UNION
SELECT * SELECT *
FROM EMPREGADO NATURAL JOIN DEPARTAMENTO FROM EMPREGADO EMP RIGHT OUTER JOIN CATEGORIA CAT
ON ( EMP.codCat < CAT.codCat )
◼ Esquema de Relação resultante
❑ ???( cod_Emp, nomeEmp, codCat, codDep, codEmpChefe, nomeDep,
localizacao )
CATEGORIA( codCat, nomeCat, salarioBase )
DEPARTAMENTO( codDep, nomeDep, localizacao )
EMPREGADO( cod_Emp, nomeEmp, codCat, codDep, codEmpChefe )
61 63 65
61 63 65
De notar a omissão de AS
62 64 66
62 64 66
11
Funções de Agregação (cont.) Funções de Agregação (cont. 2) Sub-Interrogação (cont.)
◼ Qual o total de nomes diferentes dos empregados em ‘Lisboa’ ?
◼ COUNT( * ) ◼ Qual o código do departamento do(s) empregado(s) 'Carlos Castro' ?
❑ COUNT 5 ( ( localizacao = ‘Lisboa’ ( DEPARTAMENTO ) ) EMPREGADO )
❑ número total de linhas
SELECT COUNT( DISTINCT E.nomeEmp )
SELECT DISTINCT E2.codDep
FROM DEPARTAMENTO AS D INNER JOIN EMPREGADO AS E
◼ COUNT( [DISTINCT] <coluna> ) ON ( D.codDep = E.codDep ) FROM EMPREGADO AS E2
WHERE localizacao = ‘Lisboa’ WHERE E2.nome = 'Carlos Castro‘
❑ número de linhas excluindo as que, para a coluna indicada, têm valor NULL.
Caso se use DISTINCT não se consideram valores duplicados
◼ Qual o valor total dos salários base a pagar aos empregados do ◼ Qual o nome dos empregados do(s) departamento(s) com os códigos
departamento 1 e qual o valor de IRS (calculado a 22%)?
◼ SUM( [DISTINCT] <expressão> ) obtidos na interrogação anterior, mas que não são ‘Carlos Castro’ ?
❑ SUM salarioBase, SUM (salarioBase*0.17) ( ❑ assumindo que existem cinco empregados com o nome ‘Carlos Castro’ e
❑ somatório dos valores [diferentes] da expressão
( codDep = 1 ( EMPREGADO ) ) 3=1 CATEGORIA ) que que três deles estão no departamento 4, um está no 7 e outro no 11
SELECT SUM( C.salarioBase ), SUM( C.salarioBase * 0.22 ) AS IRS
◼ AVG( [DISTINCT] <expressão> ) FROM EMPREGADO AS E INNER JOIN CATEGORIA AS C SELECT DISTINCT E1.nome
❑ média (SUM / COUNT) dos valores [diferentes] da expressão ON ( E.codCat = C.codCat )
FROM EMPREGADO AS E1
WHERE codDep = 1
WHERE E1.nome <> 'Carlos Castro' AND
◼ SUM e AVG apenas se aplicam a valores numéricos CATEGORIA( codCat, nomeCat, salarioBase ) E1.codDep IN ( 4, 7, 11 )
DEPARTAMENTO( codDep, nomeDep, localizacao )
EMPREGADO( cod_Emp, nomeEmp, codCat, codDep, codEmpChefe )
67 69 71
67 69 71
68 70 72
68 70 72
12
Sub-Interrogação Não-Correlacionada Cláusula WHERE Predicados (cont.)
◼ Foi anteriormente apresentada a sintaxe geral de uma questão SQL ◼ LIKE: pesquisa cadeias de caracteres com determinado padrão
◼ Numa Sub-Interrogação Não-Correlacionada a interrogação interior não
SELECT [DISTINCT] <colunas> | *
necessita dos valores da interrogação exterior ◼ comparação (=, <>, >, <, >=, <=) e BETWEEN
FROM <tabelas>
❑ WHERE nomeEmp = ‘Manuel Silva’
◼ Quais os códigos e nomes das categorias com menor salário base ? [WHERE <condição>]
❑ WHERE codEmp BETWEEN 1 AND 5
SELECT C.codCat, C.nome ◼ IN
◼ <condição>
FROM CATEGORIA AS C ❑ WHERE codCat IN ( 1, 2 )
WHERE C.salarioBase = ❑ consiste numa colecção de “Predicados”
( SELECT MIN( D.salarioBase ) ◼ ANY (em pelo menos um valor *), ALL (em todos os valores *)
FROM CATEGORIA AS D ) ◼ Cada “Predicado”, ❑ WHERE salarioBase > ANY ( SELECT … )
❑ pode envolver qualquer composição de sub-expressões do mesmo tipo,
◼ EXISTS (se existe pelo menos uma linha *)
◼ A interrogação interior (SELECT MIN(… ) não depende da exterior ❑ combinada com os operadores lógicos AND, OR, NOT e parêntesis
❑ WHERE EXISTS ( SELECT … )
❑ a interrogação interior é executada em primeiro lugar e apenas uma vez
❑ a relação devolvida na interrogação interior permite resolver a exterior ◼ Cada “Predicado”, ◼ Teste de valor nulo
❑ quando avaliado produz um valor lógico verdadeiro ou falso, para o tuplo ❑ WHERE comissao IS NULL
considerado * da subquery
73 75 77
73 75 77
74 76 78
13
IN ANY, ALL EXISTS, NOT EXISTS
◼ Verifica se um valor está contido numa coluna de uma tabela, ou numa ◼ Verifica se todas (ALL) ou algumas (ANY) linhas, da subquery, têm um
◼ Verifica a existência de, pelo menos, uma linha numa tabela
lista de valores atributo que obedece a uma expressão envolvendo operadores
relacionais ◼ [NOT] EXISTS (sub-interrogação)
◼ <construtor de linha> [NOT] IN
( {sub-interrogação | lista de expressões escalares} ) ◼ <construtor de linha> <comparação> {ALL | ANY} (sub-interrogação) ◼ Quais os departamentos que têm pelo menos um empregado ?
◼ Quais as categorias dos empregados com maior salário efectivo ? ◼ Qual o nome dos empregados cujo salário efectivo é superior ao de SELECT D.*
alguns empregados da mesma categoria ? FROM DEPARTAMENTO AS D
SELECT C.* CATEGORIA( codCat, nome, salarioBase )
WHERE EXISTS
EMPREGADO( codEmp, nome, salarioEfectivo, codCat, codDep )
FROM CATEGORIA AS C ( SELECT *
SELECT E.nome
WHERE C.codCat IN FROM EMPREGADO AS E
FROM EMPREGADO AS E
( SELECT E.codCat WHERE E.codDep = D.codDep )
WHERE E.salarioEfectivo > ANY
FROM EMPREGADO AS E
( SELECT E1.salarioEfectivo
WHERE E.salarioEfectivo =
FROM EMPREGADO E1 ◼ A condição do WHERE é verdadeira se,
( SELECT MAX( F.salarioEfectivo )
WHERE E.codCat = E1.codCat ) ❑ o resultado da sub-interrogação for não vazio.
FROM EMPREGADO AS F ) )
❑ substituindo ANY por ALL teríamos como resultado uma Relação vazia
79 81 83
79 81 83
80 82 84
80 82 84
14
EXISTS (cont. 1) Comparação ( = )
◼ Quais os departamentos que têm pelo menos um empregado ? ◼ Quais as categorias com maior salário base ?
SELECT C.codCat
Comando Select – order by,
❑ sem utilizar o Predicado EXISTS, temos as seguintes soluções:
FROM CATEGORIA AS C
SELECT D.* WHERE C.salarioBase =
FROM DEPARTAMENTO AS D
WHERE ( SELECT COUNT( codEmp )
( SELECT MAX( C1.salarioBase )
FROM CATEGORIA AS C1 ) group by e having
FROM EMPREGADO AS E
WHERE E.codDep = D.codDep ) > 0 ◼ Qual o código e nome dos empregados com maior salário base ?
SELECT E.codEmp, E.nome
SELECT DISTINCT D.* FROM EMPREGADO AS E INNER JOIN CATEGORIA AS C Select …
FROM DEPARTAMENTO AS D INNER JOIN EMPREGADO AS E ON ( E.codCat = C.codcat) from …
ON ( D.codDep = E.codDep ) WHERE C.salarioBase = where …
( SELECT MAX( C1.salarioBase ) group by…
FROM CATEGORIA AS C1 ) having …
order by …
DEPARTAMENTO( codDep, nome, localizacao )
CATEGORIA( codCat, nome, salarioBase )
EMPREGADO( codEmp, nome, salarioEfectivo, codCat, codDep )
85 87 89
85 87 89
86 88 90
86 88 90
15
ORDER BY GROUP BY HAVING
◼ Ordena a relação resultante, por ordem crescente ou decrescente de ◼ Produz uma linha de resultados por cada conjunto de linhas com o ◼ Aplica uma ou mais condições a cada grupo de linhas especificado pela
uma ou mais expressões de ordenação mesmo valor da expressão de agrupamento cláusula GROUP BY
❑ é sempre a última cláusula a ser especificada ❑ Permite, por exemplo, aplicar funções de agregação a grupos de linhas de ❑ Se a cláusula GROUP BY não for utilizada, o grupo considerado é o de todas
uma tabela. as linhas resultantes do SELECT
SELECT [DISTINCT] <colunas> | * ◼ A cláusula HAVING é usada para definir restrições a grupos, assim
FROM <tabela>, ... SELECT [DISTINCT] <colunas> | * como a cláusula WHERE é usada para definir restrições a linhas.
[WHERE <condição>] FROM <tabela>, ... SELECT [DISTINCT] <colunas> | *
[ORDER BY <expressão de ordenação> [ASC | DESC], … ] [WHERE <condição>] FROM <tabela>, ...
[GROUP BY <expressão de agrupamento>] [WHERE <condição>]
◼ ASC: ordenação ascendente (ascending), valor por omissão [GROUP BY <expressão de agrupamento>]
◼ A cláusula SELECT apenas pode conter: [HAVING <condição>]
◼ DESC: ordenação descendente (descending)
❑ colunas que apareçam na cláusula GROUP BY e,
◼ Utilização das cláusulas HAVING e WHERE
❑ funções de agregação aplicadas a quaisquer outras colunas
❑ a cláusula HAVING deve sempre conter funções de agregação
❑ a cláusula WHERE nunca contém funções de agregação
91 93 95
91 93 95
92 94 96
92 94 96
16
WHERE, GROUP BY, HAVING e ORDER BY
◼ Pretende-se uma lista onde conste, para cada código de departamento
o valor do menor salário efectivo pago a empregados da categoria com
código ‘C1’. Só se pretendem os departamentos para os quais esse
menor salário efectivo seja superior ao menor salário base de todas as
categorias. Os valores mais altos devem ser apresentados primeiro.
97
97
98
98
17