17 - consultas em sql - iceb.ssdi.di.fct.unl.pticeb.ssdi.di.fct.unl.pt/1718/files/ice-b-17.pdf · 1...
TRANSCRIPT
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
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
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
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'
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)
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...)