ICE-B 17 - Consultas em SQL Ludwig Krippahl
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 1
Consultas em SQL Cruzar tabelas 2
Cruzar tabelas Informação pode estar em várias tabelas Filmes: Filme_id Titulo Tipo Classificacao 101 Sexto Sentido suspense drama maiores de 12 102 Regresso ao Futuro comedia aventura maiores de 6 103 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 103 Artur Lopes da Silva Rua da Guerra 12 123412341234123402 Av.Liberdade 202 123412341234123403............ 3
Cruzar tabelas Informação pode estar em várias tabelas Alugueres: Aluguer_id Cliente_id Filme_id Data_aluguer Data_entrega 1001 108 102 2018/05/10 2018/05/11 1002 106 101 2018/05/12 1003 102 107 2018/05/13 1004 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 4
Cruzar tabelas Produto cartesiano das tabelas SELECT Clientes.Nome, Alugueres.Data_Aluguer from Clientes, Alugueres; Clientes.Nome Alugueres.Data_Aluguer Artur Meireles 2018/05/10 Artur Meireles 2018/05/12 Artur Meireles 2018/05/13 Artur Meireles 2018/05/11...... Isabel Lopes da Silva 2018/05/10 Isabel Lopes da Silva 2018/05/12 Isabel Lopes da Silva 2018/05/13 Isabel Lopes da Silva 2018/05/11...... 5
Cruzar tabelas Se não é ambíguo, podemos omitir a tabela do atributo sqlite> SELECT Nome, Data_Aluguer from Clientes, Alugueres; Nome Data_Aluguer Artur Meireles 2018/05/10 Artur Meireles 2018/05/12 Artur Meireles 2018/05/13 Artur Meireles 2018/05/11...... Isabel Lopes da Silva 2018/05/10 Isabel Lopes da Silva 2018/05/12 Isabel Lopes da Silva 2018/05/13 Isabel Lopes da Silva 2018/05/11...... 6
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_Aluguer Antonio Jose Seguro 2018/05/10 Vitor Gaspar 2018/05/12 Joana Fonseca 2018/05/13 Isabel Lopes da Silva 2018/05/11 Nota: Cliente_ID existe em ambas; temos de indicar tabela 7
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_Aluguer Antonio Jose Seguro 2018/05/10 Vitor Gaspar 2018/05/12 Joana Fonseca 2018/05/13 Isabel Lopes da Silva 2018/05/11 8
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_Aluguer Antonio Jose Seguro 2018/05/10 Vitor Gaspar 2018/05/12 Joana Fonseca 2018/05/13 Isabel Lopes da Silva 2018/05/11 9
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 Titulo Antonio Jose Seguro 2018/05/10 Regresso ao Futuro Vitor Gaspar 2018/05/12 Sexto Sentido Joana Fonseca 2018/05/13 Dia da Independencia Isabel Lopes da Silva 2018/05/11 Regresso ao Futuro 10
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_entrega 1001 108 102 2018/05/10 2018/05/11 1002 106 101 2018/05/12 1003 102 107 2018/05/13 1004 104 102 2018/05/11 2018/05/14 11
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 Titulo Vitor Gaspar 2018/05/12 Sexto Sentido Joana 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 12
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 Titulo Vitor 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 13
Consultas em SQL Funções de agregação 14
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; 15
Funções de agregação Contagens: COUNT Aluguer_id Cliente_id Filme_id Data_aluguer Data_entrega 1001 108 102 2018/05/10 2018/05/11 1002 106 101 2018/05/12 1003 102 107 2018/05/13 1004 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 16
Funções de agregação Contagens: COUNT Aluguer_id Cliente_id Filme_id Data_aluguer Data_entrega 1001 108 102 2018/05/10 2018/05/11 1002 106 101 2018/05/12 1003 102 107 2018/05/13 1004 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 17
Funções de agregação Contagens: COUNT Quantos "Lopes" existem? Cliente_id Nome Morada 101 Artur Meireles Rua da Paz 20 102 Joana Fonseca Rua da Guerra 1234 103 Artur Lopes da Silva Av.Liberdade 202 104 Isabel Lopes da Silva Rua do La Vem Um 1 105 Passos Coelho Av. Massama 20-3 106 Vitor Gaspar Rua do 5 % 8 107 Cavaco Silva Boliqueime 108 Antonio Jose Seguro Largo do Rato 2 sqlite3> SELECT COUNT(*) FROM Clientes WHERE Nome LIKE "%Lopes%"; 2 18
Funções de agregação Valores extremos: MIN e MAX Aluguer_id Cliente_id Filme_id Data_aluguer Data_entrega 1001 108 102 2018/05/10 2018/05/11 1002 106 101 2018/05/12 1003 102 107 2018/05/13 1004 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 19
Consultas em SQL Python: strings e SQL 20
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 estar delimitadas 21
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' 22
Consultas em SQL Trabalho Prático 2 23
TP2 Problema: ajudar optimizar produção de insulina Insulina humana é produzida com microorganizmos geneticamente modificados (neste caso, Escherichia coli) 24
TP2 Problema: ajudar optimizar produção de insulina Investigadores crescem E. coli modificada num reactor Tiram amostras, medem concentração de insulina (no citoplasma) 25
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 ajuda para processar os dados 26
TP2 Objectivo: processar um ficheiro de comandos BASE_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) 27
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)... 28
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 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 *;*;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 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 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 31
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 y = βx x y β = x i y i x i n 2 x 1 i n ( ) : Tempo em horas : [Insulina] g/l 1 x i 2 y i 32
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 33
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. 34
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 35
TP2 Entrega Como no primeiro trabalho: Enviar.zip para praticasice@gmail.com Usar endereço oficial da FCT O ficheiro.zip tem de conter um ficheiro tp2.py que implementa a função processar(ficheiro) O.zip pode conter outros módulos.py mas não deve ter o Sqlite3 nem ficheiros de dados. Prazo de entrega termina a 3 de Junho às 12:00 (meio dia) 36
Consultas em SQL Resumo 37
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 2 Próximas teóricas 25/5: Integração numérica e simulação; apoio ao TP2 1/6: Revisões e dúvidas Leitura recomendada: Capítulo 17 dos apontamentos (a partir de Domingo, espero...) 38