SóProvas


ID
126853
Banca
CESGRANRIO
Órgão
Petrobras
Ano
2010
Provas
Disciplina
Banco de Dados
Assuntos

Seja o seguinte esquema de banco de dados.

Cliente(IdCliente: Integer, NomeCliente: Varchar(120));
Produto(IdProduto: Integer, NomeProduto: Varchar(120));
Pedido(IdPedido: Integer, IdCliente: Integer referencia Cliente(IdCliente));
Item(IdPedido: Integer referencia Pedido(IdPedido), IdProduto: Integer referencia Produto(IdProduto), Quantidade: Integer);

Considere que os atributos sublinhados correspondam à chave primária da respectiva relação e os atributos que são seguidos da palavra "referencia" sejam chaves estrangeiras. Com base no esquema apresentado, qual comando SQL permite obter uma lista contendo os nomes dos clientes e dos produtos por eles comprados com a quantidade total de cada produto por cliente?

Dado:
A lista deverá conter somente clientes que já compraram pelo menos 2 produtos diferentes, independente do pedido, ou que nunca compraram nenhum produto, sendo que deverá estar ordenada pelo nome do cliente e, a seguir, pelo nome do produto.

Alternativas
Comentários
  • Apesar de ser uma questão aparentemente monstruosa, devemos gastar nosso raciocínio apenas no final de cada SELECT. Nesta questão bastaria considerar as cláusulas WHERE E HAVING. No final de pergunta foi solicitado 2 produtos diferentes ou nenhum. Daí já descartamos as alternativas B, D e E. Restando A e C, bastar lembrar do conceito de HAVING, que não consegue comparar "ou esse, ou aquele", como é o caso da resposta da C. já com o where você consegue fazer esta comparação. Portanto, a resposta certa é a alternativa A.
  • Grande Janssen,permita-me discordar. Se eu estiver errado, por favor, me corrija para eu aprender corretamente.No meu entendimento, não existe qualquer problema em usar várias condições em uma cláusula HAVING. A cláusula HAVING se comporta de forma idêntica à cláusula WHERE, exceto por um detalhe: o WHERE define o resultado que você quer buscar na sua base de dados. O HAVING opera sobre o resultado que você já buscou na base. É como se fosse uma cama de filtro superior na qual você já tem um resultado e sobre ele quer aplicar um filtro.Por este motivo a cláusula WHERE não funciona sobre Alias de tableas (count(*) as TOTAL where total>2). O alias não existe no banco. Portanto, sobre a coluna do alias (TOTAL) somente pode operar o cláusula having. Ela opera sobre um resultado que já existe, e nele conseguirá filtrar o TOTAL.Verifiquei no site do PCI e identifiquei que o gabarito é C.Aqui encontra-se as provas e os gabaritos para download:http://site.pciconcursos.com.br/download/prova14342515.zip
  • No site da Cesgranrio o gabarito está confirmado como A
  • Leoh, o alias total existe sim e para usar o HAVING a funcao agregadora deveria estar logo apos o HAVING.
  • Meus cents!
    Apesar de realmente a resposta ser a letra A, o processo de eliminação do Janssen está equivocado. Vejamos:

    Como é pedido uma lista de clientes que tenham comprado mediante uma condição ou que nunca tenham comprado, precisaremos de uma junção a esquerda. Outra não serviria pois não retornaria todos os registros a esquerda. Assim elinar-se-ia as letra C e E.

    Outra incorreção da letra C é percebida ao se analisar o jogo de parenteses feito pela banca.
    (cliente.idcliente in
                 (select idcliente from
                              (select idcliente,count(*) as total from
                                          (select distinct cliente.idcliente,item.idproduto from cliente
                                                       inner join pedido on cliente.idcliente = pedido.idcliente
                                                       inner join item on pedido.idpedido = item.idpedido
                                          ) clienteTotal
                                          group by idcliente
                              ) filtrocliente
                              having (total>=2)
                 )
    )
    select idcliente from (select idcliente,count(*) …(select distinct … ) clienteTotal group by idcliente ) filtrocliente having (total>=2)

    Notem que essa sentença nem compila pois ela insere um having sem o group by

     
    Continuando com o jogo de parenteses, diga-se de passagem: isso que dificulta a questão, deve-se atentar que o OR (Produto.NomeProduto IS NULL) é disjunção de WHERE (Cliente.IDCliente IN ... ( ()) ...)) e não de WHERE (total >= 2)))

    As outras duas opões com LEFT OUTER JOIN (B e D), não possuem o teste de produto nulo, e a D ainda faz um LEFT OUTER JOIN no select mais interno, troca os testes having/where e pior ainda, faltam parentesis para fechar.
  • Não entendi como a letra A pode trazer os clientes "que nunca compraram nenhum produto" se no filtro de clientes exite um INNER entre CLIENTE e PEDIDO. O cliente que nunca comprou produto é o cliente que nunca fez pedido (a menos que, por padrão, todos os clientes entrem na base com um pedido sem item). Se ele não tem nenhum pedido na base, ele não será selecionado quando vc fizer um INNER entre CLIENTE e PEDIDO.

    Onde tá o furo desse raciocínio? Alguem pode ajuar?

    Só por esse motivo, eu questiono a A. O restante dela me parece certo.