Laboratório de Banco de Dados Linguagens SQL e PL/SQL Aula 8 SELECT com GROUP BY e HAVING 1
Comando SELECT O comando SELECT é formado pelas cláusulas SELECT, FROM, WHERE, ORDER BY, GROUP BY, HAVING, START WITH...CONNECT BY, FOR UPDATE e NOWAIT. Estas cláusulas permitem recuperar dados de uma ou mais tabelas ou visões, especificar uma ou mais condições, ordenar ou computar dados por grupos de linhas, etc. Utilização: recuperacão de dados de um banco de dados como parte do comando de inserção como parte do comando atualização Comando SELECT Sintaxe: SELECT [ALL DISTINCT] colunas [FROM tabelas visões snapshots subconsultas,...] [WHERE cláusula] [START WITH cláusula [CONNECT BY cláusula]] [GROUP BY cláusula [HAVING cláusula]] [ORDER BY cláusula] [FOR UPDATE cláusula [NOWAIT]] 2
A Cláusula WHERE A cláusula WHERE especifica critérios para determinar o conjunto de linhas a ser recuperado (seleção) select colunas from tabelas where condições Select nome from usuarios where nome like 'A%'; Textos e Datas Textos e datas sempre devem ser colocados entre aspas simples (') A comparação de textos diferencia maiúsculas e minúsculas As datas suportam diferentes formatos de representação 3
Critérios de Seleção de Linhas Os critérios de seleção de linhas são baseados em: Operadores de Comparação: =, <, >, <=, >=, <> Expressões de Intervalos: BETWEEN AND Expressões sobre Conjuntos: IN, ANY, SOME, ALL, EXISTS Critérios de Seleção de Linhas Comparações por Similaridade: LIKE Valores Nulos: IS [NOT] NULL 4
Operador IN É utilizado como o operador de conjuntos pertence select * from enderecos where cod_cidade in (12, 45, 61); Operador LIKE Utilizado para comparações de textos por similaridade %: representa qualquer seqüência de caracteres _: representa um único caracter Select * from usuarios where nome like 'M_ri_ da Silva %' 5
Operador LIKE Muito cuidado ao utilizar o operador LIKE Se forem utilizados os caracteres % e _ no ínicio do texto, não serão utilizados índices na consulta Exemplos Seleção de linhas utilizando operadores de comparação na cláusula WHERE Operadores de comparação between in like is [not] null 6
Conectivos Lógicos Os conectivos lógicos AND e OR representam a união de duas condições. AND retorna um resultado quando todas as condições são verdadeiras OR retorna um resultado quando uma das condições é verdadeira O conectivo lógico NOT retorna um resultado quando a condição de pesquisa é falsa. Exemplos select * from usuarios where nome like 'Carlos%' and email like '%@dell.com' select * from produtos where importado='s' or preco > 3000; select * from telefones where cod_tipo_telefone not in (1,5,8) 7
A Cláusula ORDER BY A cláusula ORDER BY ordena os resultados de consultas baseado em uma ou mais colunas. A ordem pode ser crescente (ASC) ou decrescente (DESC) Caso não seja especificada ordem assume-se ASC, por padrão Exemplo Select * from usuarios order by cpf asc; Select * from enderecos order by cod_cidade, cep desc, rua desc, numero A(s) coluna(s) da cláusula ORDER BY não precisam necessariamente aparecer na cláusula SELECT 8
A Tabela DUAL A tabela DUAL é uma tabela dummy Ela contém somente uma coluna chamada dummy e apenas uma linha que contém o valor 'X' Ela é utilizada sempre que se deseja retornar uma única linha em uma consulta Exemplos select * from dual; select 'teste' texto_fixo from dual; select sysdate from dual; 9
Datas Datas são armazenadas internamente como: Século, ano, mês, dia, hora, minuto e segundo Podem ser utilizados diversos formatos para as datas SYSDATE é a função que retorna a data e hora atuais Operações com Datas date + number = date date number = date date date = número de dias date + number/24 = date, com um determinado número de horas a mais 10
Funções Funções sobre linhas Operam sobre cada linha do resultado individualmente Funções sobre conjuntos de linhas Operam sobre diversas linhas, calculando valores sobre todo o conjunto (totais, médias, o maior valor, etc.) Funções Numéricas ABS(n), ACOS(n), ASIN(n), ATAN(n), ATAN2(n), CEIL(n), COS(n), COSH(n), EXP(n), FLOOR(n), LN(n), LOG(n), MOD(n,m), POWER(n,m), ROUND(n,m), SIGN(n), SIN(n), SINH(n), SQRT(n), TAN(n), TANH(n), TRUNC(n,m) 11
Funções sobre Caracteres Mudança de maiúsculas e minúsculas: LOWER(s), UPPER(s), INITCAP(s) Eliminação de espaços: LTRIM(s1,s2), RTRIM(s1,s2) Outras: CONCAT(s1,s2), LPAD(s1,n,s2), RPAD(s1,n,s2), LENGTH(s), SUBSTR(s,n,m), REPLACE(s1,s2,s3), CHR(n), SOUNDEX(s), TRANSLATE(s1,s2,s3), etc. Utilizando Funções ORACLE oferece inúmeras funções: Funções Matemáticas: ABS(n): valor absoluto de n SELECT ABS(-15) Valor Absoluto FROM DUAL; CEIL(n): retorna o primeiro inteiro maior ou igual SELECT CEIL(18.7) "Ceil" FROM DUAL; Ceil --------- 19 12
Utilizando Funções FLOOR(n): retorna o primeiro inteiro menor ou igual SELECT FLOOR(18.7) Floor" FROM DUAL; Floor --------- 18 MOD(n,m): retorna o resto de uma divisão SELECT MOD(20,3) Módulo" FROM DUAL; Módulo --------- 2 Utlizando Funções POWER(n,m): retorna uma potência SELECT POWER(3,4) Potência" FROM DUAL; Potência ------------ 27 ROUND(n[,m]): arredonda n para m casas decimais (se omitido é zero) SELECT ROUND(18.78276,1) Round" FROM DUAL; Round --------- 18.8 13
Utilizando Funções TRUNC(n[,m]): trunca o resultado m casas decimais (se omitido é zero)(se menor que zero, zera dígitos a esquerda da vírgula) SELECT TRUNC(18.78276,1) Trunc " FROM DUAL; Trunc --------- 18.7 SELECT TRUNC(5618.78276,-2) Trunc" FROM DUAL; Trunc --------- 5600 Utilizando Funções Funções de Caracteres: INITCAP(s): torna as iniciais maiúsculas SELECT INITCAP('joão da silva') Nome " FROM DUAL; Nome -------------------- 'João Da Silva' LOWER(s): passa para minúsculas SELECT LOWER('TesTE DE minúsculas') Lower " FROM DUAL; Lower -------------------------- teste de minúsculas 14
Utilizando Funções LPAD(c1,n,c2): retorna a seqüência de caracteres c1, preenchida à esquerda por n caracteres c2 (se omitido são utilizados espaços em branco) SELECT LPAD('Teste',12,'*') Lpad FROM DUAL; Lpad ---------------- *******Teste LTRIM(s1,s2): remove da esquerda de s1 a seqüência s2 SELECT LTRIM('3434343434567890','34') Ltrim FROM DUAL; Ltrim ---------- 567890 Utilizando Funções REPLACE(s1,s2,s3): substitui s2 por s3 em s1 SELECT REPLACE('Teste de Banco de Dados','Banco de Dados','Oracle') Ltrim FROM DUAL; Ltrim --------------------- Teste de Oracle RPAD(c1,n,c2): equivalente ao LPAD, mas preenchendo à direita RTRIM(s1,s2): equivalente ao RTRIM, mas removendo à direita SUBSTR(s,n[,m]): retorna a substring de s, iniciando em n até m (se omitido vai até o final) 15
Utilizando Funções SOUNDEX(s): retorna uma string com a representação fonética de s select soundex(substr(nome,1,7)) Soundex,nome Nome from alunos where soundex(substr(nome,1,7)) = soundex('andré') order by 1 Soun Nome ------- ------------------------------------------------------------ A536 Andre Madeira A536 André Antoniazzi A536 Anderson de Oliveira A536 André Trein A536 Andrei Paiva Utilizando Funções UPPER(s): passa para maiúsculas INSTR(s1,s2[,n[,m]]): retorna a posição de s1 em que ocorre s2, iniciando a busca em n e finalizando em m select INSTR('Teste especial','es'] Posição from dual; Posição ----------- 2 LENGHT(s): retorna o tamanho de s 16
Utilizando Funções Funções de Data e Hora ADD_MONTHS(d,n): adiciona n meses na data d select ADD_MONTHS('21-mar-98',5] Data from dual; Data --------------- 21-AUG-98 ROUND(d[,f]): formata a data d de acordo com f (se omitido, formata como dia) select ROUND('21-mar-98'] Data from dual; Data --------------- 21-AUG-98 Utilizando Funções Funções de Conversão TO_CHAR(d[,f]): converte para caracteres a expressão n segundo o formato f select TO_CHAR('21-mar-98','DD, Month, YYYY') Data from dual; Data -------------------------- 21, March, 1998 TO_DATE(s[,f]): converte a expressão s para data select to_date('march 21, 1998, 11:00 A.M.', 'Month dd, YYYY, HH:MI A.M.') Data from dual; Data --------------- 21-MAR-98 17
Utilizando Funções Outras Funções NVL(expr1,expr2): se expr1 for nula, retorna expr2 select nome Nome, NVL(carga_horaria,0) Carga Horária from Disciplinas order by 1; UID e USER: retornam, respectivamente, o identificador único e o nome do usuário (login) conectado ao SGBD Oracle select UID, USER from dual; UID USER -------- -------------------------------------------------- 12 ALUNO1 Função TRUNC Select trunc(preco*1.2379,2) from produtos; Select trunc(preco*1.2379,0) from produtos; Select trunc(preco*1.2379,-1) from produtos; 18
Funções de Conversão O Oracle converte automaticamente em atribuições: Varchar2 e char para number Varchar2 e char para date Number para varchar2 Date para varchar2 Desde que seja possível Funções de Conversão O Oracle converte implicitamente em expressões: Varchar2 e char para number Varchar2 e char para date 19
Funções de Conversão As principais funções de conversão são: TO_CHAR(<number ou date>, <formato>) TO_NUMBER(<char ou varchar2>) TO_DATE(<char ou varchar2>, <formato>) Formatos de Datas YYYY, YY, Y: ano MONTH, MON, MM, RM: mês por extenso, abreviado, com 2 dígitos e em romanos DDD, DD, D, DAY, DY: dia do ano, dia do mês, dia da semana (domingo = 1) e dia da semana por extenso e abreviado Q, WW, W: quarter, semana do ano, semana do mês 20
Formatos de Horas HH ou HH12, HH24: horas MI: minutos SS: segundos SSSSS: segundos após a meia noite /,,,. : pontuação texto : pode ser inserido entre aspas Formatos de Números 9: posição numérica 0: posição numérica com 0 na máscara L: símbolo de moeda local.: ponto decimal,: separador de milhar 21
Conversão de Datas select to_char(sysdate, 'dd/mm/yyyy') from dual; select to_char(sysdate, 'dd/mm/yyyy h24:mi:ss') from dual; select to_char(sysdate, 'day, dd de month de yyyy') from dual Conversão de Datas to_date('21/03/1971'', 'dd/mm/yyyy') Retorna um date a partir de uma seqüência de caracteres, convertendo de acordo com o formato definido É a única maneira de garantir a correção do resultado 22
Conversão de Números to_char(1234.679, 'L999,990.00') = 'R$ 1,234.67') to_number('456,786.76') = 456786.76 Funções sobre Datas MONTHS_BETWEEN(d1,d2): retorna o número de meses entre duas datas ADD_MONTHS(d1,n): adiciona meses em uma data NEXT_DAY(d,'dia da semana'): encontra o próximo dia da semana a partir de uma data LAST_DAY(d): encontra o último dia do mês da data 23
Funções sobre Datas ROUND(d): arredonda uma data round('21-mar-71','month') = 01-apr-71 round('21-mar-71','year') = 01-jan-72 TRUNC(d): trunca uma data trunc('21-mar-71','month') = 01-mar-71 trunc('21-mar-71','year') = 01-jan-71 Função NVL Converte NULL para algum valor operável nvl(null, 0) = 0 select nvl(importado,'x') from produtos; 24
Função DECODE Realiza um se-então-senão sobre um valor decode(coluna ou expressão, busca1, resultado1, busca2, resultado2,...) select decode(importado, 's', 'produto importado', 'n', 'produto nacional') from produtos; Função DECODE DECODE(expr,expr1,result1,expr2,result2,...,padrão): compara expr com expr1, se for igual, retorna result1, senão, compara com expr2 e assim sucessivamente. Se nenhuma comparação for verdadeira, retorna padrão. Exemplo: select nome Nome, decode(formacao, 'G','Graduação', 'E','Especialização', 'M','Mestrado', 'D','Doutorado', 'Desconhecida') Formacao from PROFESSORES order by 1; 25
Expressões CASE CASE expressão WHEN expressão THEN expressão_retorno... ELSE expressão_retorno CASE Expressões CASE WHEN condição THEN expressão_retorno... ELSE expressão_retorno 26
Exemplo select case nivel_privilegio when 2 then 'Baixo' when 3 then 'Médio-Baixo' when 4 then 'Médio' when 5 then 'Médio-Alto' when 6 then 'Alto' else 'Outros' end from administradores; Exemplo select case when nivel_privilegio >= 1 and nivel_privilegio < 5 then 'Baixo' when nivel_privilegio >= 5 and nivel_privilegio < 7 then 'Médio' when nivel_privilegio >= 7 and nivel_privilegio < 10 then 'Alto' else 'Outros' End from administradores; 27
SQL SELECT GROUP BY HAVING Funções sobre Conjuntos de Linhas Permitem calcular Valores totais para toda uma tabela Sub-totais para toda uma tabela, agrupando o resultado por determinado atributo e apresentando-o como uma nova coluna Para o cálculo de totais agrupados, utilizam-se as funções agregadas juntamente à cláusula GROUP BY 28
Funções sobre Conjuntos de Linhas SELECT função_agregada FROM nome_da_tabela [...] onde, função_agregada pode ser: AVG ([ALL DISTINCT] nome_da_coluna) SUM ([ALL DISTINCT] nome_da_coluna) COUNT ([ALL DISTINCT] nome_da_coluna) COUNT (*) MAX([ALL DISTINCT] nome_da_coluna) MIN([ALL DISTINCT] nome_da_coluna) STDDEV ([ALL DISTINCT] nome_da_coluna) VARIANCE ([ALL DISTINCT] nome_da_coluna) Exemplos Select avg(preco) media from produtos; Select avg(nvl(preco,0)) media from produtos; Select max(preco) from produtos; Select count(*) num_clientes from clientes; Select count(ddd) from telefones; Retorna somente os não-nulos 29
A Cláusula GROUP BY A cláusula GROUP BY pode ser utilizada para agrupar os resultados de uma consulta, gerando sub-totais por grupos em novas colunas A Cláusula GROUP BY SELECT nome_da_coluna [,...], função_agregada [,...] FROM nome_da_tabela [,...] GROUP BY [ALL] nome_da_coluna [,...] ORDER BY colunas O operador ALL inclui no resultado todos os grupos, incluindo aqueles que não atendem às condições de busca A(s) coluna(s) contidas na cláusula SELECT deve(m) estar todas obrigatoriamente na cláusula GROUP BY Mas as colunas da cláusula GROUP BY não precisam estar na cláusula SELECT 30
A Cláusula HAVING A cláusula HAVING determina as condições sobre as quais será realizada a composição dos grupos A Cláusula HAVING SELECT nome_da_coluna [,...] FROM nome_da_tabela [,...] GROUP BY nome_da_coluna [,...] HAVING condições As novas colunas geradas pelo cálculo das funções agregadas podem ser referidas na cláusula HAVING 31
Exemplos select importado, avg(preco) from produtos group by importado; select cid.nome, count(*) from cidades cid, enderecos end where cid.cod_cidade = end.cod_cidade group by cid.nome having count(*) > 10; 32