30
Pesquisas em Bases de Dados com SQL Tipicamente, um comando de pesquisa em SQL tem a seguinte estrutura sintática: Select A1,A2,...An from T1,T2,...Tm where Predicado; As palavras Select, from e where são palavras-chave. A1,A2,...An são atributos tipicamente das tabelas. T1,T2,...Tm são tabelas. Predicado contém um conjunto de condições booleanas que resultam numa avaliação de Verdade ou Falso para cada tuplo psquisado determinando a sua inclusão ou não na lista de resultados. O Predicado pode não existir, não havendo por isso restrições. Apresentam-se, em língua natural, as perguntas sobre a BD do Clube de Vídeo que desenhámos e as respectivas queries em SQL que produzem as soluçoes: 1 Quais os nomes dos vários sócios? SQL> Select nome_socio from socio; nome_socio ------------- Antonio Silva Maria Luz Helena Cunha Joo Chaves Paulo Sousa Pedro Sousa Miguel Branco Fernando Pret Luis Figo Cristiano Ron Joana Chaves Paula Sousa Pedro Sequeir Manuel Branco Fernanda Pret Luisa Figo Cristiana Ron Joo Rodrigues Jorge Sampaio Mrio Soares

Pesquisas em Bases de Dados com SQL · 2020. 5. 3. · Pesquisas em Bases de Dados com SQL Tipicamente, um comando de pesquisa em SQL tem a seguinte estrutura sintática: Select A1,A2,...An

  • Upload
    others

  • View
    4

  • Download
    1

Embed Size (px)

Citation preview

  • Pesquisas em Bases de Dados com SQL

    Tipicamente, um comando de pesquisa em SQL tem a seguinte estrutura sintática:

    Select A1,A2,...An from T1,T2,...Tm where Predicado;

    As palavras Select, from e where são palavras-chave. A1,A2,...An são atributos tipicamente das

    tabelas. T1,T2,...Tm são tabelas. Predicado contém um conjunto de condições booleanas que

    resultam numa avaliação de Verdade ou Falso para cada tuplo psquisado determinando a sua

    inclusão ou não na lista de resultados. O Predicado pode não existir, não havendo por isso

    restrições.

    Apresentam-se, em língua natural, as perguntas sobre a BD do Clube de Vídeo que desenhámos

    e as respectivas queries em SQL que produzem as soluçoes:

    1 Quais os nomes dos vários sócios?

    SQL> Select nome_socio from socio;

    nome_socio

    -------------

    Antonio Silva

    Maria Luz

    Helena Cunha

    Joo Chaves

    Paulo Sousa

    Pedro Sousa

    Miguel Branco

    Fernando Pret

    Luis Figo

    Cristiano Ron

    Joana Chaves

    Paula Sousa

    Pedro Sequeir

    Manuel Branco

    Fernanda Pret

    Luisa Figo

    Cristiana Ron

    Joo Rodrigues

    Jorge Sampaio

    Mrio Soares

  • 2 Quais os nomes e datas de nascimento dos vários sócios (modifique o cabeçalho para a data

    de nascimento)?

    SQL> Select nome_socio, data_nsc_socio “nasceu em” from socio;

    NOME_SOCIO nasceu em

    ----------------------------------- ---------

    Antonio Silva 12-JUN-40

    Maria Luz 12-JUN-42

    Helena Cunha 12-JUN-42

    João Chaves 21-OCT-62

    Pedro Sousa 21-OCT-63

    Paulo Sousa 21-DEC-82

    Miguel Branco 07-FEB-92

    Fernando Preto 13-FEB-91

    Luis Figo 02-JUL-73

    Cristiano Ronaldo 02-MAR-93

    Joana Chaves 22-OCT-62

    NOME_SOCIO nasceu em

    ----------------------------------- ---------

    Paula Sousa 21-APR-93

    Pedro Sequeira 22-DEC-89

    Manuel Branco 06-MAY-92

    Fernanda Preto 13-FEB-81

    Luisa Figo 02-JUL-73

    Cristiana Ronaldo 02-MAR-93

    João Rodrigues 22-MAR-73

    Jorge Sampaio 12-SEP-33

    Mário Soares 12-DEC-23

    20 rows selected.

    3 Quais os números de sócio, moradas e telefones dos vários sócios?*

    SQL> Select num_socio, morada_socio,tlf_socio from socio;

    NUM_SOCIO MORADA_SOCIO TLF_SOCIO

  • ---------- ----------------------------------- ---------------

    1 Rua das Flores, nº 5, Lisboa 214565488

    2 Rua das Árvores, nº 5, Lisboa 217887998

    3 Rua das Estradas, nº 43, Almada 919297895

    4 Av. das Palmeiras, nº 430, Mafra 919337895

    5 Av. das Formigas, nº 30, Estoril 969334895

    6 Av. das Cigarras, nº 30, Estoril 96935895

    7 Rua da Escola Velha, nº 13, Parede 969378821

    8 Rua do Azar, nº 13, Vila Franca 131313131

    9 Rua do êxito, nº 7, Cova da Piedade 7777777

    10 Rua das fintas, nº 7, Funchal 7888777

    11 Av. das Laranjeiras, nº 431, Mafra 91933754

    NUM_SOCIO MORADA_SOCIO TLF_SOCIO

    ---------- ----------------------------------- ---------------

    12 Av. dos Rios, nº 300, Linhó 969334895

    13 Av. dos Cigarros, nº 305, Sintra 98935875

    14 Rua da Escola, nº 13, Parede 969338821

    15 Rua da Sorte, nº 113, Setubal 21212121

    16 Rua do êxito, nº 77, Caparica 7777777

    17 Rua do futebol, nº 7, Funchal 78008777

    18 Rua do Electrico, nº 7, Porto 78000077

    19 Palácio de Belém, nº 7, Lisboa 218765477

    20 Campo Grande, nº 1, Lisboa 2187658885

    20 rows selected.

    4 Quais os números e nomes dos sócios masculinos?

    SQL> Select num_socio, nome_socio from socio where sexo_socio = ‘M’;

    NUM_SOCIO NOME_SOCIO

    ---------- -----------------------------------

    1 Antonio Silva

    4 João Chaves

    5 Pedro Sousa

    6 Paulo Sousa

    7 Miguel Branco

  • 8 Fernando Preto

    9 Luis Figo

    10 Cristiano Ronaldo

    13 Pedro Sequeira

    14 Manuel Branco

    18 João Rodrigues

    NUM_SOCIO NOME_SOCIO

    ---------- -----------------------------------

    19 Jorge Sampaio

    20 Mário Soares

    13 rows selected.

    5 Quantos sócios tem o video-clube?

    SQL> select count(*) from socio;

    COUNT(*)

    ---------

    20

    6 Quantos sócios femininos tem o video-clube (altere o cabeçalho da contagem para “número

    de senhoras”)?*

    SQL> select count(*) as “número de senhoras” from socio where sexo_socio = ‘F’ ;

    número de senhoras

    ------------------

    7

    7 Qual a idade de cada sócio (altere o cabeçalho para “idade”)?

    SQL> select nome_socio,trunc((sysdate - data_nsc_socio)/365.25) as idade from socio;

    NOME_SOCIO IDADE

    ----------------------------------- ----------

    Antonio Silva 69

    Maria Luz 67

    Helena Cunha 67

  • João Chaves 46

    Pedro Sousa 45

    Paulo Sousa 26

    Miguel Branco 17

    Fernando Preto 18

    Luis Figo 36

    Cristiano Ronaldo 16

    Joana Chaves 46

    NOME_SOCIO IDADE

    ----------------------------------- ----------

    Paula Sousa 16

    Pedro Sequeira 19

    Manuel Branco 17

    Fernanda Preto 28

    Luisa Figo 36

    Cristiana Ronaldo 16

    João Rodrigues 36

    Jorge Sampaio 75

    Mário Soares 85

    20 rows selected.

    8 Qual a idade de cada sócio homem com mais de 40 anos (altere o cabeçalho para “idade”)?

    SQL> define idade = ”trunc((sysdate - data_nsc_socio)/365.25)”

    SQL> select nome_socio,&idade as idade from socio where &idade > 40 and sexo_socio =

    ‘M’;

    NOME_SOCIO IDADE

    ----------------------------------- ----------

    Antonio Silva 69

    João Chaves 46

    Pedro Sousa 45

    Jorge Sampaio 75

    Mário Soares 85

    9 Qual a idade de cada sócio mulher com idade entre 20 e 30 anos?*

  • SQL> select nome_socio,&idade from socio where sexo_socio = ‘F’ and &idade >= 20 and

    &idade select nome_socio,&idade from socio where sexo_socio = ‘F’ and &idade between 20

    and 30;

    NOME_SOCIO TRUNC((SYSDATE-DATA_NSC_SOCIO)/365.25)

    ----------------------------------- --------------------------------------

    Fernanda Preto 28

    10 Quantos sócios (homens) e quantas sócias existem, ou seja, quantos sócios existem por

    sexo?

    SQL> select sexo_socio,count(*) from socio group by sexo_socio;

    S COUNT(*)

    - ----------

    F 7

    M 13

    11 Qual o sócio mais velho?

    SQL> select nome_socio from socio where &idade = all(select max(&idade) from socio);

    NOME_SOCIO

    -----------------------------------

    Mário Soares

    12 Qual o sócio mais novo?*

    NOME_SOCIO

    -----------------------------------

    Cristiano Ronaldo

    Paula Sousa

    Cristiana Ronaldo

    13 Para cada filme, qual o seu nome e o nome do género de que faz parte?

  • SQL> select nome_filme,nome_genero from filme natural inner join genero;

    %ou

    SQL> select nome_filme,nome_genero from filme f, genero g where f.cod_genero =

    g.cod_genero;

    NOME_FILME NOME_GENERO

    ----------------------------------- -------------------------

    O padrinho I Acção

    O padrinho II Acção

    O padrinho III Acção

    Nova Iorque fora de horas Cómico

    O pianista Dramático

    O piano Romântico

    O sentido da vida Cómico

    Libertinagens Poucas Vergonhas

    Beldades em férias Poucas Vergonhas

    Sherlock Holmes Policial

    Crime disse ela Policial

    NOME_FILME NOME_GENERO

    ----------------------------------- -------------------------

    Amores a torto e adireito Romântico

    Os 101 Dalmatas Familiar

    Shine a Light Musical

    Amadeus Familiar

    Taxi driver Familiar

    16 rows selected.

    14 Para cada filme, qual o seu nome e o nome da editora de que faz parte?*

    SQL> select nome_filme, nome_editora from filme natural inner join editora

    NOME_FILME NOME_EDITORA

    ----------------------------------- -----------------------------------

    O padrinho I Lusomundo

    O padrinho II Lusomundo

  • O padrinho III Lusomundo

    Nova Iorque fora de horas FilmesFilmes

    O pianista FilmesFilmes

    O piano Lusomundo

    O sentido da vida FilmesFilmes

    Libertinagens FilmesFilmes

    Beldades em férias FilmesFilmes

    Sherlock Holmes FilmesFilmes

    Crime disse ela Lusomundo

    NOME_FILME NOME_EDITORA

    ----------------------------------- -----------------------------------

    Amores a torto e adireito Lusomundo

    Os 101 Dalmatas FilmesFilmes

    Shine a Light FilmesFilmes

    Amadeus FilmesFilmes

    Taxi driver FilmesFilmes

    16 rows selected.

    15 Para cada género, quantos filmes existem no vídeo-clube (indique o nome do género)?

    SQL> select nome_genero,count(*) from filme natural inner join genero group by

    nome_genero;

    NOME_GENERO COUNT(*)

    ------------------------- ----------

    Acção 3

    Cómico 2

    Dramático 1

    Familiar 3

    Musical 1

    Policial 2

    Poucas Vergonhas 2

    Romântico 2

    8 rows selected.

  • 16 Para cada género, quantos filmes existem no vídeo-clube (indique o nome do género e

    ordena a lista por contagem de forma descendente)?

    SQL> select nome_genero,count(*) from filme natural inner join genero group by

    2 nome_genero order by count(*) desc;

    NOME_GENERO COUNT(*)

    ------------------------- ----------

    Acção 3

    Familiar 3

    Cómico 2

    Policial 2

    Romântico 2

    Poucas Vergonhas 2

    Dramático 1

    Musical 1

    8 rows selected.

    17 Para cada filmes, quantas cópias existem, alugadas ou não (indique o nome do filme)? *

    SQL> select nome_filme,count(*) from filme natural inner join copia group by

    nome_filme;

    NOME_FILME COUNT(*)

    ----------------------------------- ----------

    Amadeus 3

    Amores a torto e adireito 3

    Beldades em férias 3

    Crime disse ela 3

    Libertinagens 3

    Nova Iorque fora de horas 3

    O padrinho I 3

    O padrinho II 3

    O padrinho III 3

    O pianista 3

    O piano 3

  • NOME_FILME COUNT(*)

    ----------------------------------- ----------

    O sentido da vida 3

    Os 101 Dalmatas 3

    Sherlock Holmes 3

    Shine a Light 3

    Taxi driver 3

    16 rows selected.

    18 Quais os nomes dos filmes do género cómico?

    SQL> select nome_filme from filme natural inner join genero where

    2 upper(nome_genero) like 'C_MICO';

    NOME_FILME

    -----------------------------------

    Nova Iorque fora de horas

    O sentido da vida

    19 Quais os géneros para os quais existe no vídeo-clube exactamente 1 filme (indique o nome

    do género)?

    SQL> select nome_genero,count(*) from filme natural inner join genero group by

    2 nome_genero having count(*) = 1;

    NOME_GENERO COUNT(*)

    ------------------------- ----------

    Dramático 1

    Musical 1

    20 Quais os géneros para os quais existem no vídeo-clube mais do que 2 filmes (indique o

    nome do género)?

  • SQL> select nome_genero,count(*) from filme natural inner join genero group by

    nome_genero having count(*) > 2;

    NOME_GENERO COUNT(*)

    ------------------------- ----------

    Acção 3

    Familiar 3

    21 Quais os actores do filme “O Padrinho III”?

    SQL > select nome_actor from actor natural inner join filme_actor natural inner join filme

    where nome_filme =’O padrinho III’;

    %ou ainda, para uma pesquisa menos ingrata

    SQL > select nome_actor from actor natural inner join filme_actor natural inner join filme

    where upper(nome_filme) like ’%PADRINHO III’;

    NOME_ACTOR

    -----------------------------------

    Al Pacino

    Marlon Brando

    22 Quais os nomes dos actores (não repita nomes) que já entraram em filmes realizados por

    Copolla (Copolla, embora seja um nome suficientemente discriminante, é apenas um dos

    nomes deste realizador). ?

    SQL> select distinct nome_actor from actor natural inner join filme_actor natural inner join

    filme_realizador natural inner join realizador where upper(nome_realizador) like

    ‘%COP%OL%A’;

    NOME_ACTOR

    -----------------------------------

    Al Pacino

    Antony Hopkins

    Marlon Brando

    Mick Jagger

  • Robert de Niro

    23 Quais os actores (os nomes sem repetição) que entraram em qualquer dos filmes O

    Padrinho I, II ou III? (use o operador like combinado com o caracter %).

    SQL> select distinct nome_actor from actor natural inner join

    filme_actor natural inner join filme where upper(nome_filme) = 'O PADRINHO I'

    or upper(nome_filme) = 'O PADRINHO II'

    or upper(nome_filme) = 'O PADRINHO III';

    % ou

    SQL> select distinct nome_actor from actor natural inner join

    filme_actor natural inner join filme where upper(nome_filme)

    in ('O PADRINHO I','O PADRINHO II','O PADRINHO III');

    % ou ainda,

    SQL> select distinct nome_actor from actor natural inner join

    2 filme_actor natural inner join filme where upper(nome_filme)

    3 like '%PADRINHO%';

    NOME_ACTOR

    -----------------------------------

    Al Pacino

    Marlon Brando

    Robert de Niro

    24 Quais os actores que já entraram em pelo menos 2 filmes diferentes?

    SQL> select distinct nome_actor from actor a,filme_actor fa1, filme_actor fa2 where

    fa1.cod_filme != fa2.cod_filme and fa1.cod_actor = fa2.cod_actor and fa2.cod_actor =

    a.cod_actor;

    NOME_ACTOR

    -----------------------------------

    Al Pacino

    Antony Hopkins

    John Gleese

    Julia Roberts

  • Marlon Brando

    Meryl Streep

    Mick Jagger

    Robert de Niro

    8 rows selected.

    25 Qual o outro filme em que um dos actores do filme ‘Shine a Light’ também entrou?*

    SQL> select f2.nome_filme from filme f2,filme f1,filme_actor fa1,filme_actor fa2 where

    f1.cod_filme

    != f2.cod_filme and fa1.cod_filme = f1.cod_filme and fa2.cod_filme = f2.cod_filme

    2 and fa1.cod_actor = fa2.cod_actor and upper(f1.nome_filme) like

    3 'SHINE%LIGHT';

    NOME_FILME

    -----------------------------------

    Amadeus

    26 Qual a média de filmes alugados por sócio?

    SQL> select avg(count(*)) from aluguer group by num_socio;

    AVG(COUNT(*))

    -------------

    1.8

    27 Quais os filmes nunca alugados?

    SQL> select nome_filme from filme where cod_filme not in (select cod_filme from aluguer);

    NOME_FILME

    -----------------------------------

    Amadeus

    Taxi driver

    28 Quais os filmes não alugados este mês?

    SQL> select nome_filme from filme where cod_filme not in (select cod_filme from aluguer

    where to_char(data_aluguer,’MON’) = to_char(sysdate,’MON’));

    NOME_FILME

  • -----------------------------------

    O pianista

    Libertinagens

    O padrinho III

    Amadeus

    Amores a torto e adireito

    Sherlock Holmes

    O sentido da vida

    Nova Iorque fora de horas

    Shine a Light

    Taxi driver

    Beldades em férias

    NOME_FILME

    -----------------------------------

    Os 101 Dalmatas

    O padrinho I

    O padrinho II

    Crime disse ela

    15 rows selected.

    29 Quais os filmes de acção não alugados este mês?*

    SQL> select nome_filme from filme natural inner join genero where upper(nome_genero)

    like ‘AC__O’ and cod_filme not in (select cod_filme from aluguer where

    to_char(data_aluguer,’MON’) = to_char(sysdate,’MON’));

    NOME_FILME

    -----------------------------------

    O padrinho III

    O padrinho I

    O padrinho II

    30 Qual o filme mais alugado desde sempre?

    SQL> select nome_filme from filme natural inner join aluguer group by nome_filme having

    count(*) in (select max(count(*)) from aluguer group by cod_filme);

  • SQL> select nome_filme from filme natural inner join aluguer group by nome_filme having

    count(*) in (select max(count(*)) from aluguer group by cod_filme);

    NOME_FILME

    -----------------------------------

    Sherlock Holmes

    31 Qual o filme com mais realizadores?*

    SQL> select nome_filme from filme natural inner join filme_realizador group by nome_filme

    having count(*) in (select max(count(*)) from filme_realizador group by cod_filme);

    NOME_FILME

    -----------------------------------

    Beldades em férias

    32 Qual o socio que mais filmes alugou desde sempre?*

    SQL> select nome_socio from socio natural inner join aluguer group by nome_socio having

    count(*) in (select max(count(*)) from aluguer group by num_socio);

    NOME_SOCIO

    -----------------------------------

    Cristiana Ronaldo

    33 Quais os sócios com devoluções em atraso ?

    SQL> select distinct nome_socio from socio natural inner join aluguer natural inner join

    filme where (data_aluguer + dias_sem_multa_filme) < sysdate and

    (cod_filme, num_copia, data_aluguer,num_socio) not in (select

    cod_filme,num_copia,data_aluguer,num_socio from devolucao);

    NOME_SOCIO

    -----------------------------------

    Antonio Silva

    Fernanda Preto

    Fernando Preto

    Helena Cunha

  • Joana Chaves

    João Chaves

    Luis Figo

    Manuel Branco

    Maria Luz

    Miguel Branco

    Paula Sousa

    NOME_SOCIO

    -----------------------------------

    Paulo Sousa

    Pedro Sousa

    13 rows selected.

    34 Quais os sócios e os filmes relativos a devoluções em atraso há mais de um mês?*

    SQL> select distinct nome_socio,nome_filme from socio natural inner join aluguer natural

    inner join filme where (data_aluguer + dias_sem_multa_filme) < sysdate - 30 and

    (cod_filme, num_copia, data_aluguer,num_socio) not in (select

    cod_filme,num_copia,data_aluguer,num_socio from devolucao);

    NOME_SOCIO NOME_FILME

    ----------------------------------- ----------------------------

    Antonio Silva O padrinho I

    Antonio Silva O sentido da vida

    Fernanda Preto Amores a torto e adireito

    Fernando Preto Libertinagens

    Helena Cunha O padrinho II

    Joana Chaves Sherlock Holmes

    João Chaves O padrinho III

    Luis Figo Beldades em férias

    Luis Figo Sherlock Holmes

    Manuel Branco Os 101 Dalmatas

    Maria Luz O padrinho I

    NOME_SOCIO NOME_FILME

    ----------------------------------- ----------------------------

  • Maria Luz O padrinho II

    Miguel Branco O piano

    Paula Sousa Crime disse ela

    Paulo Sousa O pianista

    Pedro Sousa Nova Iorque fora de horas

    35 Quais os sócios que já viram filmes de todos os generos?

    SQL> select nome_socio from socio natural inner join aluguer natural inner join filme group

    by nome_socio having count(distinct(cod_genero)) = all (select count(cod_genero) from

    genero);

    no rows selected.

    36 Quanto deve o sócio número N ?

    SQL> select nvl(sum((least(data_aluguer + dias_sem_multa_filme -1,

    to_date(to_char(sysdate,'DD-MON-YYYY'),'DD-MON-YYYY')) - data_aluguer + 1) *

    preco_dia_filme + ( to_date(to_char(sysdate,'DD-MON-YYYY'),'DD-MON-YYYY') - least(

    data_aluguer + dias_sem_multa_filme -1, to_date(to_char(sysdate,'DD-MON-

    YYYY'),'DD-MON-YYYY'))) * multa_dia_filme),0) as deve from aluguer natural inner join

    filme where num_socio = &num_socio and

    (cod_filme,num_copia,data_aluguer,num_socio) != all (select

    cod_filme,num_copia,data_aluguer,num_socio from devolucao);

    Enter value for num_socio: 1

    old 1: select nvl(sum((least(data_aluguer + dias_sem_multa_filme,

    to_date(to_char(sysdate,'DD-M

    new 1: select nvl(sum((least(data_aluguer + dias_sem_multa_filme,

    to_date(to_char(sysdate,'DD-M

    DEVE

    ----------

    5852

    37 Qual a receita (em dinheiro) dos alugueres no mês corrente, até à presente data. Crie as

    views que achar convenientes)?

  • %Uma view é uma tabela que se cria tipicamente a partir de outras. Tem a vantagem de

    sentir as alterações feitas naquelas a partir das quais ela foi criada. É usada para vários fins:

    esconder pormenores que, por vezes não interessam; obter vistas parciais para facilitar a

    elaboração de pesquisas complexas.

    Vamos primeiro criar uma view que nos dê o cod_filme, o num_copia, a data_aluguer e o

    num_socio dos alugueres nao devolvidos.

    SQL> create or replace view aluguerNaoDevolvido as select cod_filme as

    cod_filme,num_copia as num_copia, data_aluguer as data_aluguer,num_socio as

    num_socio, to_date(to_char(sysdate,'DD-MON-YYYY'),'DD-MON-YYYY') as data_fim

    from aluguer where (cod_filme,num_copia,data_aluguer,num_socio) not in (select

    cod_filme,num_copia,data_aluguer,num_socio from devolucao);

    View created.

    % Agora vamos criar outra view com campos idênticos mas para os alugueres devolvidos

    depois do princípio do mês corrente.

    SQL> Create or replace view aluguerDevolvido as select cod_filme as cod_filme,num_copia

    as num_copia, data_aluguer as data_aluguer, num_socio as num_socio, data_devolucao

    as data_fim from aluguer natural inner join devolucao where data_devolucao >=

    to_date('01-'||to_char(sysdate,'MON-YYYY'),'DD-MON-YYYY');

    View created.

    % Agora vamos criar outra view correspondente à união das duas anteriores.

    SQL> create or replace view aluguerDesteMes as select cod_filme as cod_filme,num_copia

    as num_copia, data_aluguer as data_aluguer,num_socio as num_socio, data_fim as

    data_fim from aluguerNaoDevolvido

    union select cod_filme as cod_filme,num_copia as num_copia, data_aluguer as

    data_aluguer, num_socio as num_socio, data_fim as data_fim from aluguerDevolvido;

    % A ultima view determina que dinheiro foi ganho pelo video-clube, o que corresponde ao

    somatório de cada aluguer, em que para cada aluguer calcula-se a soma do valor sem

    multa e do valor da multa, tendo em conta o número de dias de cada período.

    SQL> create or replace view receitaDesteMes as select sum( (least(

    greatest(data_aluguer + dias_sem_multa_filme -1,

    to_date('01-'||to_char(sysdate,'MON-YYYY'),'DD-MON-YYYY') ),data_fim) -

    greatest(data_aluguer,

  • to_date('01-'||to_char(sysdate,'MON-YYYY'),'DD-MON-YYYY')) +1) *

    preco_dia_filme + least(data_fim - least(data_aluguer +

    dias_sem_multa_filme -1,data_fim) +1, data_fim -

    to_date('01-'||to_char(sysdate,'MON-YYYY'),'DD-MON-YYYY') +1) * multa_dia_filme ) as

    receitaDesteMes from aluguerDesteMes natural inner join filme;

    View created.

    %Vamos pois ler a view produtoDesteMes.

    SQL> select * from receitaDesteMes;

    RECEITADESTEMES

    ---------------

    2524

    38 Crie uma view que reporte para cada sócio, o seu nome e o número de multas que ele já

    pagou. A lista só deve conter sócios com multas não nulas e deve ser ordenada pelo número

    de multas de forma descendente.

    SQL> create or replace view sociosNumeroMultas as select nome_socio as

    nome_socio,count(*) as NumeroDeMultas from socio natural inner join aluguer natural

    inner join devolucao natural inner join filme where data_aluguer +

    dias_sem_multa_filme < data_devolucao group by nome_socio order by count(*) desc;

    View created.

    SQL> select * from sociosNumeroMultas;

    NOME_SOCIO NUMERODEMULTAS

    ----------------------------------- --------------

    Cristiana Ronaldo 7

    Antonio Silva 1

    Manuel Branco 1

  • 39 Em média, qual o género de filme mais tempo conservado pelo sócio em casa?

    40 Qual a distribuição de géneros de filme pelas idades (décadas das idades) de sócios?

    SQL> select trunc(((data_aluguer - data_nsc_socio)/365.25) / 10) * 10 as

    decada,nome_genero,count(*) from socio natural inner join aluguer natural inner join

    filme natural inner join genero group by trunc(((data_aluguer - data_nsc_socio)/365.25)

    / 10) * 10,nome_genero order by trunc(((data_aluguer - data_nsc_socio)/365.25) / 10) *

    10,count(*) desc;

    DECADA NOME_GENERO COUNT(*)

    ---------- ------------------------- ----------

    10 Policial 3

    10 Cómico 2

    10 Musical 2

    10 Familiar 2

    10 Poucas Vergonhas 2

    10 Acção 1

    10 Dramático 1

    10 Romântico 1

    20 Dramático 1

    20 Romântico 1

    30 Policial 1

    DECADA NOME_GENERO COUNT(*)

    ---------- ------------------------- ----------

    30 Poucas Vergonhas 1

    40 Cómico 2

    40 Acção 1

    40 Policial 1

    60 Acção 4

    60 Cómico 1

    60 Romântico 1

    18 rows selected.

    41 Qual a distribuição de generos de filme por cada sexo do sócio?*

  • SQL> select sexo_socio as sexo,nome_genero,count(*) from socio natural inner join

    aluguer natural inner join filme natural inner join genero group by sexo_socio,

    nome_genero order by sexo_socio, count(*) desc;

    S NOME_GENERO COUNT(*)

    - ------------------------- ----------

    F Acção 4

    F Policial 3

    F Cómico 2

    F Musical 1

    F Familiar 1

    F Dramático 1

    F Romântico 1

    F Poucas Vergonhas 1

    M Cómico 3

    M Acção 2

    M Romântico 2

    S NOME_GENERO COUNT(*)

    - ------------------------- ----------

    M Policial 2

    M Poucas Vergonhas 2

    M Musical 1

    M Familiar 1

    M Dramático 1

    16 rows selected.

    42 Qual a distribuição dos géneros de filme alugados, ao longo dos meses? Será que no natal se

    vêem mais filmes do tipo familiar? E na Primavera?*

    SQL> select to_char(data_aluguer,'MON') as dia,nome_genero,count(*) from socio natural

    inner join aluguer natural inner join filme natural inner join genero group by

    to_char(data_aluguer,'MON'),nome_genero order by

    to_char(data_aluguer,'MON'),count(*) desc;

    DIA NOME_GENERO COUNT(*)

  • --- ------------------------- ----------

    APR Cómico 2

    AUG Cómico 1

    FEB Acção 2

    JAN Acção 2

    JAN Poucas Vergonhas 1

    JUL Romântico 2

    JUN Musical 1

    JUN Dramático 1

    MAR Acção 2

    MAR Familiar 2

    MAR Cómico 2

    DIA NOME_GENERO COUNT(*)

    --- ------------------------- ----------

    MAR Musical 1

    MAR Policial 1

    MAR Dramático 1

    MAR Poucas Vergonhas 1

    MAY Romântico 1

    NOV Policial 2

    OCT Policial 1

    SEP Policial 1

    SEP Poucas Vergonhas 1

    20 rows selected.

    43 Qual a distribuição de géneros de filmes alugados por dia da semana (sugestão: use a funcão

    to_char(data,’Day’) que lhe dá o dia da semana)?*

    SQL> select to_char(data_aluguer,'Day') as dia,nome_genero,count(*) from socio natural

    inner join aluguer natural inner join filme natural inner join genero group by

    to_char(data_aluguer,'Day'), nome_genero order by to_char(data_aluguer,'Day'),

    count(*) desc;

    DIA NOME_GENERO COUNT(*)

    --------- ------------------------- ----------

    Friday Acção 1

  • Friday Dramático 1

    Monday Cómico 3

    Monday Acção 2

    Monday Poucas Vergonhas 2

    Monday Musical 1

    Monday Familiar 1

    Monday Policial 1

    Monday Dramático 1

    Saturday Familiar 1

    Sunday Cómico 1

    DIA NOME_GENERO COUNT(*)

    --------- ------------------------- ----------

    Thursday Acção 1

    Thursday Cómico 1

    Thursday Policial 1

    Thursday Poucas Vergonhas 1

    Tuesday Policial 2

    Tuesday Romântico 2

    Tuesday Acção 1

    Tuesday Musical 1

    Wednesday Acção 1

    Wednesday Policial 1

    Wednesday Romântico 1

    22 rows selected.

    SQL>

    44 Faça uma view ordenada por nome de sócio, que tenha além disso o seu telefone, para que

    se lhe possa telefonar porque «hoje» ele faz anos e, por isso mesmo, o vídeo-clube oferece-

    lhe um aluguer gratuitamente. Isto significa que sempre que consulta a view, esta lhe dá os

    sócios que nesse dia são aniversariantes. Use a função to_char(Data,‘DD-MON’)* que lhe dá

    o dia e o mês da data Data.

    SQL> create view fazemAnosHoje as select nome_socio as nome_socio,tlf_socio as tlf_socio

    from socio where to_char(sysdate,'DD-MON') = to_char(data_nsc_socio,'DD-MON');

  • View created.

    SQL> select * from fazemAnosHoje;

    no rows selected

    45 Crie uma view que dê a despesa que cada sócio fez no vídeo-clube desde sempre. Considere

    apenas a despesa efectiva; não o que o cliente deve.

    SQL> create or replace view despesasocios as select nome_socio as nome_socio,sum(

    (least(data_devolucao, data_aluguer + dias_sem_multa_filme -1) - data_aluguer + 1) *

    preco_dia_filme +

    Greatest(0,(data_devolucao - (data_aluguer + dias_sem_multa_filme -1)))*

    multa_dia_filme ) as

    soma from socio natural inner join devolucao natural inner join filme group by nome_socio;

    View created.

    SQL> select * from despesasocios;

    NOME_SOCIO SOMA

    ----------------------------------- ----------

    Antonio Silva 450

    Cristiana Ronaldo 227

    Pedro Sousa 16

    Cristiano Ronaldo 8

    46 Crie uma view que apresente a despesa relativa que cada sócio fez no vídeo-clube desde

    sempre. Por despesa relativa entenda-se a despesa que o sócio fez mas tendo em conta há

    quanto tempo o é no vídeo-clube. Assuma a primeira data de empréstimo do sócio como a

    data em que ele se fez sócio. Considere novamente apenas a despesa efectiva; não a que o

    cliente deve.**

    %vamos dividir o problema em pequenos problemas.

  • SQL> create or replace view socioDataInicio as select nome_socio as

    nome_socio,min(data_aluguer) as Data_Inicio_Socio from socio natural inner join

    aluguer group by nome_socio;

    View created.

    SQL> select * from socioDataInicio;

    NOME_SOCIO DATA_INIC

    ----------------------------------- ---------

    Antonio Silva 01-JAN-08

    Cristiana Ronaldo 12-MAR-07

    Cristiano Ronaldo 01-OCT-08

    Fernanda Preto 20-MAY-08

    Fernando Preto 01-JAN-09

    Helena Cunha 04-FEB-08

    Joana Chaves 13-NOV-08

    João Chaves 12-MAR-08

    Luis Figo 01-SEP-08

    Manuel Branco 22-MAR-08

    Maria Luz 03-JAN-08

    NOME_SOCIO DATA_INIC

    ----------------------------------- ---------

    Miguel Branco 22-JUL-08

    Paula Sousa 23-SEP-08

    Paulo Sousa 20-JUN-08

    Pedro Sousa 13-APR-08

    15 rows selected.

    SQL> create or replace view despesaRelativaSocio as select nome_socio as

    nome_socio,soma/(sysdate - Data_Inicio_socio) as despesaRelativa from socioDataInicio

    natural inner join despesasocios order by soma/(sysdate - Data_Inicio_socio) desc;

    View created.

  • SQL> select * from despesaRelativaSocio;

    NOME_SOCIO DESPESARELATIVA

    ----------------------------------- ---------------

    Antonio Silva .76838356

    Manuel Branco .29446178

    Cristiana Ronaldo .197681505

    Cristiano Ronaldo .020268366

    Pedro Sousa .017129601

    47 Faça uma lista do top + desta semana (os filmes mais alugados na semana corrente)? (view)

    48 Quais os filmes que apresentam maior regularidade de alugueres ao longo do tempo (utilize

    a funçao de grupo variance(.)?

    49 Faça uma lista com o nome do filme, o numero da cópia e o número de vezes que a cópia já

    foi alugada. Mostre as cópias de cada filme juntas. (view).

    50 Faça uma view que dê a situação de cada cópia de filme, ito é: livre ou há quantos dias está

    alugada e, se em atraso, qual o valor corrente da multa?

  • nome_género

  • create view copiadisponivel as

    (select cod_filme,num_copia from copia minus

    select cod_filme, num_copia from aluguer

    where (cod_filme,num_copia,data_aluguer,num_socio) in

    (select cod_filme,num_copia,data_aluguer,num_socio from

    devolucao))

    select nome_genero,count(cod_filme) from genero

    natural inner join filme

    where cod_filme in (select cod_filme from copiadisponivel)

    group by nome_genero

    Pode ficar também numa view.