40
ICE-B 17 - Consultas em SQL Ludwig Krippahl

17 - Consultas em SQL - iceb.ssdi.di.fct.unl.pticeb.ssdi.di.fct.unl.pt/1718/files/ICE-B-17.pdf · 1 Consultas em SQL Resumo Cruzar informação entre várias tabelas • SQL: JOIN

Embed Size (px)

Citation preview

ICE-B

17 - Consultas em SQL

Ludwig Krippahl

1

Consultas em SQL

Resumo■ Cruzar informação entre várias tabelas• SQL: JOIN

■ Funções de agregação■ Juntar strings e parâmetros em Python: format e join■ Trabalho prático 2

2

Consultas em SQL

Cruzar tabelas

3

Cruzar tabelas

Informação pode estar em várias tabelas■ Filmes:

Filme_id Titulo Tipo Classificacao101 Sexto Sentido suspense drama maiores de 12102 Regresso ao Futuro comedia aventura maiores de 6103 Monstros e Cia. animacao maiores de 4... ... ... ...

■ Clientes:Cliente_id Nome Morada Numero_cartao_credito

101 Artur Meireles Rua da Paz 20 123412341234123401

102 Joana Fonseca Rua da Guerra12 123412341234123402

103 Artur Lopes daSilva Av.Liberdade 202 123412341234123403

... ... ... ...

4

Cruzar tabelas

Informação pode estar em várias tabelas■ Alugueres:

Aluguer_id Cliente_id Filme_id Data_aluguer Data_entrega1001 108 102 2018/05/10 2018/05/111002 106 101 2018/05/121003 102 107 2018/05/131004 104 102 2018/05/11 2018/05/14

■ Precisamos de cruzar a informação■ O SELECT permite seleccionar combinações de registos entre

várias tabelas

5

Cruzar tabelas

Produto cartesiano das tabelasSELECT Clientes.Nome, Alugueres.Data_Aluguer from Clientes, Alugueres;

Clientes.Nome Alugueres.Data_AluguerArtur Meireles 2018/05/10Artur Meireles 2018/05/12Artur Meireles 2018/05/13Artur Meireles 2018/05/11... ...Isabel Lopes da Silva 2018/05/10Isabel Lopes da Silva 2018/05/12Isabel Lopes da Silva 2018/05/13Isabel Lopes da Silva 2018/05/11... ...

6

Cruzar tabelas

■ Se não é ambíguo, podemos omitir a tabela do atributo

sqlite> SELECT Nome, Data_Aluguer from Clientes, Alugueres;

Nome Data_AluguerArtur Meireles 2018/05/10Artur Meireles 2018/05/12Artur Meireles 2018/05/13Artur Meireles 2018/05/11... ...Isabel Lopes da Silva 2018/05/10Isabel Lopes da Silva 2018/05/12Isabel Lopes da Silva 2018/05/13Isabel Lopes da Silva 2018/05/11... ...

7

Cruzar tabelas

Informação pode estar em várias tabelas■ Seleccionar as combinações todas não é útil■ Mas podemos restringir a selecção:

sqlite> SELECT Nome, Data_Aluguer from Clientes, Alugueres

WHERE Clientes.Cliente_ID = Alugueres.Cliente_ID;

Nome Data_AluguerAntonio Jose Seguro 2018/05/10Vitor Gaspar 2018/05/12Joana Fonseca 2018/05/13Isabel Lopes da Silva 2018/05/11

■ Nota: Cliente_ID existe em ambas; temos de indicar tabela

8

Cruzar tabelas

Informação pode estar em várias tabelas■ É melhor reservar WHERE para a selecção de registos■ Para cruzar tabelas podemos usar ON■ Isto separa conceptualmente o cruzamento da selecção

sqlite> SELECT Nome, Data_Aluguer from Clientes, Alugueres

ON Clientes.Cliente_ID = Alugueres.Cliente_ID;

Nome Data_AluguerAntonio Jose Seguro 2018/05/10Vitor Gaspar 2018/05/12Joana Fonseca 2018/05/13Isabel Lopes da Silva 2018/05/11

9

Cruzar tabelas

Informação pode estar em várias tabelas■ Se o atributo tiver o mesmo nome, o melhor é JOIN ... USING

sqlite> SELECT Nome, Data_Aluguer

FROM Clientes JOIN Alugueres USING(Cliente_ID);

Nome Data_AluguerAntonio Jose Seguro 2018/05/10Vitor Gaspar 2018/05/12Joana Fonseca 2018/05/13Isabel Lopes da Silva 2018/05/11

10

Cruzar tabelas

Quem alugou qual filme e quando?sqlite> SELECT Nome, Data_Aluguer, Titulo FROM Clientes

JOIN Alugueres USING(Cliente_ID)

JOIN Filmes USING(Filme_ID);

Nome Data_Aluguer TituloAntonio Jose Seguro 2018/05/10 Regresso ao FuturoVitor Gaspar 2018/05/12 Sexto SentidoJoana Fonseca 2018/05/13 Dia da IndependenciaIsabel Lopes da Silva 2018/05/11 Regresso ao Futuro

11

Cruzar tabelas

Quem alugou qual filme e não devolveu?■ Se não entregou ainda o campo está a NULL■ Este é um valor especial, análogo ao None do Python• Nota: não é uma string vazia... insere-se mesmo com NULL

INSERT INTO Alugueres VALUES(1001, 108, 102, '2018/05/10','2018/05/11');

INSERT INTO Alugueres VALUES(1002, 106, 101, '2018/05/12', NULL);

INSERT INTO Alugueres VALUES(1003, 102, 107, '2018/05/13', NULL);

INSERT INTO Alugueres VALUES(1004, 104, 102, '2018/05/11', '2018/05/14');

Aluguer_id Cliente_id Filme_id Data_aluguer Data_entrega1001 108 102 2018/05/10 2018/05/111002 106 101 2018/05/121003 102 107 2018/05/131004 104 102 2018/05/11 2018/05/14

12

Cruzar tabelas

Quem alugou qual filme e não devolveu?sqlite> SELECT Nome, Data_Aluguer, Titulo FROM Clientes

JOIN Alugueres USING(Cliente_ID)

JOIN Filmes USING(Filme_ID)

WHERE Data_Entrega IS NULL;

Nome Data_Aluguer TituloVitor Gaspar 2018/05/12 Sexto SentidoJoana Fonseca 2018/05/13 Dia da Independencia

■ Nota: O valor NULL deve ser testado com IS NULL• Em alternativa podemos usar outra indicação

• E.g. WHERE Data_Entrega = 'Por entregar'

• Mas NULL é o valor mais comum em campos por preencher

13

Cruzar tabelas

Quem alugou filme antes de dia 13 e não devolveu?sqlite> SELECT Nome, Data_Aluguer, Titulo FROM Clientes

JOIN Alugueres USING(Cliente_ID)

JOIN Filmes USING(Filme_ID)

WHERE Data_Entrega IS NULL AND Data_Aluguer<'2018/05/13';

Nome Data_Aluguer TituloVitor Gaspar 2018/05/12 Sexto Sentido

■ Podemos combinar várias condições com NOT, AND e OR■ Nota: neste caso podemos comparar as strings de data porque

estão no formato certo: YYYY/MM/DD

14

Consultas em SQL

Funções de agregação

15

Funções de agregação

Agregam vários registos num resultado■ Exemplos comuns:• Contagens• Máximos e mínimos (ordem lexicográfica em TEXT)• Somas

■ Sintaxe:

SELECT funcao(coluna) FROM tabela1, (JOIN) ... WHERE conds;

16

Funções de agregação

Contagens: COUNTAluguer_id Cliente_id Filme_id Data_aluguer Data_entrega

1001 108 102 2018/05/10 2018/05/111002 106 101 2018/05/121003 102 107 2018/05/131004 104 102 2018/05/11 2018/05/14

■ Quando se especifica a coluna, conta os não NULL■ Se usar * conta os registos todos.

sqlite> SELECT Count (Aluguer_ID) FROM Alugueres;

4

sqlite> SELECT Count (Data_Entrega) FROM Alugueres;

2

sqlite> SELECT Count (*) FROM Alugueres;

4

17

Funções de agregação

Contagens: COUNTAluguer_id Cliente_id Filme_id Data_aluguer Data_entrega

1001 108 102 2018/05/10 2018/05/111002 106 101 2018/05/121003 102 107 2018/05/131004 104 102 2018/05/11 2018/05/14

■ Pode ser usado com a junção de várias tabelas■ E pode incluir DISTINCT

sqlite> SELECT Count (*)

FROM Filmes JOIN Alugueres USING (Filme_ID)

WHERE Data_Entrega IS NOT NULL;

2

sqlite> SELECT COUNT(DISTINCT Filme_ID) from Alugueres;

3

18

Funções de agregação

Contagens: COUNT■ Quantos "Lopes" existem?

Cliente_id Nome Morada101 Artur Meireles Rua da Paz 20102 Joana Fonseca Rua da Guerra 1234103 Artur Lopes da Silva Av.Liberdade 202104 Isabel Lopes da Silva Rua do La Vem Um 1105 Passos Coelho Av. Massama 20 - 3106 Vitor Gaspar Rua do 5 % 8107 Cavaco Silva Boliqueime108 Antonio Jose Seguro Largo do Rato 2

sqlite3> SELECT COUNT(*) FROM Clientes WHERE Nome LIKE "%Lopes%";

2

19

Funções de agregação

Valores extremos: MIN e MAXAluguer_id Cliente_id Filme_id Data_aluguer Data_entrega

1001 108 102 2018/05/10 2018/05/111002 106 101 2018/05/121003 102 107 2018/05/131004 104 102 2018/05/11 2018/05/14

sqlite> SELECT MIN(Data_Aluguer) FROM Alugueres;

2018/05/10

sqlite> SELECT MAX(Data_Aluguer) FROM Alugueres;

2018/05/13

20

Consultas em SQL

Python: strings e SQL

21

Strings e SQL

Concatenar strings em Python■ Para criar comandos SQL será preciso combinar strings e

parâmetros■ Usar format:

In : 'INSERT INTO Table VALUES( {}, "{}", {});'.format(1,'abc','NULL') Out: 'INSERT INTO Table VALUES( 1, "abc", NULL);' In : 'INSERT INTO Table VALUES( {0}, "{1}", {2});'.format(1,'abc','NULL') Out: 'INSERT INTO Table VALUES( 1, "abc", NULL);' In : 'INSERT INTO Table VALUES( {num}, "{tex}", {nul});'\ ...: .format(num=1,tex='abc',nul='NULL') Out: 'INSERT INTO Table VALUES( 1, "abc", NULL);'

■ Nota: na string com o comando SQL as strings têm de estardelimitadas

22

Strings e SQL

Concatenar strings em Python■ Para criar comandos SQL será preciso combinar strings e

parâmetros■ Usar join para unir strings numa lista.

In : params = ['2','"abc"','NULL'] In : ', '.join( params ) Out: '2, "abc", NULL' In : conds = ['Date = "2018/05/21"', 'Cliente IS NOT NULLL', 'Conta > 2000'] In : ' AND '.join( conds ) Out: 'Date = "2018/05/21" AND Cliente IS NOT NULLL AND Conta > 2000'

23

Consultas em SQL

Trabalho Prático 2

24

TP2

Problema: ajudar optimizar produção de insulina■ Insulina humana é produzida com microorganizmos geneticamente

modificados (neste caso, Escherichia coli)

25

TP2

Problema: ajudar optimizar produção de insulina■ Investigadores crescem E. coli modificada num reactor■ Tiram amostras, medem concentração de insulina (no citoplasma)

26

TP2

Problema: ajudar optimizar produção de insulina■ Investigadores têm os dados para cada lote (batch) de teste■ Cada lote num ficheiro de texto

B-00022

EC-008

CM-207

28

S-00057;42;0.76

S-00058;53;0.98

S-00059;75;1.63

S-00060;93;1.70

S-00061;118;2.15

S-00065;133;2.70

S-00066;143;2.70

S-00086;156;3.16

Código do Lote (batch)

Código da estirpe

Código do meio de cultura

Temperatura

Amostras:

código;minutos; [Ins.] (g/L)

■ Infelizmente, não sabem programar, por isso precisam de ajudapara processar os dados

27

TP2

Objectivo: processar um ficheiro de comandosBASE_DADOS teste.db

REPORT report.txt

CRIAR_TABELAS

CARREGAR 1.txt

CARREGAR 2.txt

...

CARREGAR 19.txt

GRAFICO test.png;EC-007

ESTIRPES 28;30;CM-206

ESTIRPES *;*;CM-206

ESTIRPES 29;30;*

Ficheiro de BD

Ficheiro de relatório

Criar tabelas Lotes e Amostras

Carregar os dados para as tabelas

...

...

...

Criar o gráfico da estirpe

Relatório de estirpes

temperatura mínima e máxima

Meio de cultura

■ BASE_DADOS ficheiro• Especifica o nome do ficheiro com a base de dados (Sqlite3)

■ REPORT ficheiro• Especifica o nome do ficheiro de relatório (txt)

28

TP2

Objectivo: processar um ficheiro de comandos■ CRIAR_TABELAS• Criar as tabelas na base de dados

• Tabela Lotes id do lote, estirpe, meio e temperatura• Tabela Amostras id da amostra, id do lote, tempo, concentração

■ CARREGAR ficheiro• Carregar os dados do ficheiro para as duas tabelas

B-00022

EC-008

CM-207

28

S-00057;42;0.76

S-00058;53;0.98

...

Código do Lote (batch)

Código da estirpe

Código do meio de cultura

Temperatura

Amostras:

código;minutos; [Ins.] (g/L)

...

29

TP2

Objectivo: processar um ficheiro de comandos■ ESTIRPES minT;maxT;meio• Escrever para o ficheiro REPORT a lista de estirpes que cumprem as condições

• Temperatura de entre minT e maxT• Cultivada no meio indicado• Qualquer condição pode ser substituida por *

ESTIRPES 28;30;CM-206

■ Entre 28ºC e 30ºC (inclusive), com o meio CM-206

2 estirpes cultivadas com o meio CM-206 entre 28ºC e 30ºC

EC-013

EC-007

30

TP2

Objectivo: processar um ficheiro de comandos■ ESTIRPES minT;maxT;meio• Escrever para o ficheiro REPORT a lista de estirpes que cumprem as condições

• Temperatura de entre minT e maxT• Cultivada no meio indicado• Qualquer condição pode ser substituida por *

ESTIRPES *;*;CM-206

■ A qualquer temperatura, com o meio CM-206

3 estirpes cultivadas com o meio CM-206 entre *ºC e *ºC

EC-010

EC-013

EC-007

31

TP2

Objectivo: processar um ficheiro de comandos■ ESTIRPES minT;maxT;meio• Escrever para o ficheiro REPORT a lista de estirpes que cumprem as condições

• Temperatura de entre minT e maxT• Cultivada no meio indicado• Qualquer condição pode ser substituida por *

ESTIRPES 29;30;*

■ Qualquer meio, entre 29ºC e 30ºC (inclusive)

4 estirpes cultivadas com o meio * entre 29ºC e 30ºC

EC-011

EC-008

EC-013

EC-007

32

TP2

Objectivo: processar um ficheiro de comandos■ GRAFICO ficheiro;estirpe• Reunir todas as amostras da estirpe (qualquer meio e temperatura)• Gravar no ficheiro o gráfico com pontos e regressão linear

: Tempo em horas: [Insulina] g/L

y = βx

β =∑ − ∑ ∑xiyi

1

nxi yi

∑ −x2i1

n (∑ )xi2

x

y

33

TP2

Opcional (1 valor): melhor combinação■ Todos os dados de cada combinação estirpe, temperatura e meio• Calcular (taxa de produção de insulina, g/L/h)

■ Escrever no relatório a melhor combinação e taxa respectiva:β

...

EC-007

4 estirpes cultivadas com o meio * entre 29ºC e 30ºC

EC-011

EC-008

EC-013

EC-007

Melhor:EC-010, 36ºC, CM-202 com 1.25g/L/h

34

TP2

Critérios de avaliação■ Utilização correcta dos elementos básicos da linguagem Python.■ Decomposição adequada do problema em sub-problemas.■ Código legı́vel e documentado.■ Criação correcta das tabelas na base de dados especificada.■ Inserção correcta dos dados dos ficheiros nas tabelas respectivas

da base de dados.■ Criação e conteúdo correctos do relatório.■ Cálculo correcto da recta de regressão e criação do gráfico.

35

TP2

Critérios de avaliação■ Implementação genérica:• Pode variar o nome da base de dados, relatório e ficheiro de comandos

• Pode haver várias bases de dados e ficheiros de relatórios

• Nesse caso, gravar tudo para o último seleccionado

■ Só devem assumir que:• as tabelas são Lotes e Amostras, com os campos indicados

• os comandos a processar são os indicados

• os ficheiros referidos existem

• o GRAFICO referirá uma estirpe que existe na base de dados

• não haverá CARREGAR sem existirem as tabelas

• os comandos REPORT e BASE_DADOS aparecem pelo menos uma vez no início

36

TP2

Entrega■ Como no primeiro trabalho:• Enviar .zip para [email protected]• Usar endereço oficial da FCT

■ O ficheiro .zip tem de conter um ficheiro tp2.py que implementa afunção processar(ficheiro)

■ O .zip pode conter outros módulos .py mas não deve ter o Sqlite3nem ficheiros de dados.

■ Prazo de entrega termina a 3 de Junho às 12:00 (meio dia)

37

Consultas em SQL

Resumo

38

Resumo

Consultas em SQL■ Cruzar dados em tabelas diferentes• SELECT ... ON ou JOIN ... USING

■ Funções de agregação: COUNT MIN MAX SUM■ Métodos para juntar strings e parâmetros: join e format■ Trabalho prático 2Próximas teóricas■ 25/5: Integração numérica e simulação; apoio ao TP2■ 1/6: Revisões e dúvidasLeitura recomendada:■ Capítulo 17 dos apontamentos (a partir de Domingo, espero...)