---
# System prepended metadata

title: '#Back-end - Desafio M1'
tags: [Back-end]

---

# #Back-end - Desafio M1

##### Aluno: Pedro Ciccone
###### tags: `Back-end`

### Grupo 1 - Questões - Contagem, Agrupamentos e Comparações

**1.** Quantos bruxos nascidos-trouxa (`Muggle-born`) ou mestiços (`Half-blood`) existem em cada casa (`house`)? Ordene-os decrescentemente e limite a busca em quatro (4) registros. Observe que não temos certeza sobre `blood_status` de alguns bruxos. Mas, nós estamos buscando aqui nessa questão pelos bruxos que são `Muggle-born`, `Half-blood` ou `Muggle-born or Half-blood`.
``` javascript=
select house, count(*)
from harry_potter
where
	house is not null
	and (blood_status = 'Muggle-born'
		or blood_status = 'Half-blood'
		or blood_status = 'Muggle-born or Half-blood')
group by house
order by
	count (*) desc
	limit 4;
```
**2.** Qual é a casa que tem a menor quantidade de sangues-puro (`Pure-blood`), assumindo apenas aqueles que têm-se certeza? Remova, também, aqueles casos que a casa (`House`) seja nula e o (`Blood Status`) seja nula.
``` javascript=
select house, count(*)
from harry_potter
where
	house is not null
	and blood_status is not null
	and blood_status = 'Pure-blood'
group by house
order by
	count (*) asc
	limit 1;
```
**3.** Quantas pessoas existem na família Weasley (assuma pessoas com algum nome de Weasley)?
``` javascript=
select count(*)
from harry_potter
where
	name like '%Weasley';
```
**4.** Existe alguém na família Weasley que não seja ruivo (`Red`)?
``` javascript=
select count(*)
from harry_potter
where
	name like '%Weasley'
	and Hair_colour <> 'Red';
```
**5.** Todo bruxo consegue aprender o feitiço do patrono, um feitiço de proteção que toma forma de um animal. É um feitiço complexo e nem todos os bruxos possuem um patrono. Existem pessoas que possuem o mesmo animal patrono (`patronus`)? Remova os casos em que os valores sejam `Unknown`, `Non-corporeal` ou `None` (do inglês, desconhecido) e ordene-os pela quantidade decrescentemente, limitando nos 3 maiores resultados.
``` javascript=
select patronus, count(*)
from harry_potter
where
	patronus <> 'Unknown'
	and patronus <> 'Non-corporeal'
	and patronus <> 'None'
group by
	patronus
order by
	count(*) desc
	limit 3;
```
**6.** Utilizando apenas uma consulta, responda: busque pelos quatro bruxas ou bruxos que possuem nomes que deram origem ao nome das casas de Hogwarts (`House`). Remova aqueles que sejam da espécie fantasma (`Ghost`). A resposta deve conter o sobrenome, o nome e a espécie.
``` javascript=
select house as sobrenome, name, species
from harry_potter
where
	species <> 'Ghost'
	and (name like '%Gryffindor'
		or name like '%Slytherin'
		or name like '%Hufflepuff'
		or name like '%Ravenclaw');
```
**7.** Existiam bruxos que não eram da casa (`house`) Sonserina (`Slytherin`) que eram leais ao Lord Voldemort? Se existiram, qual são seus nomes e suas casas? Desconsidere aqueles que não estão associados a nenhuma casa. A resposta deve conter apenas o nome desses bruxos.
``` javascript=
select name
from harry_potter
where
	house <> 'Slytherin'
	and house is not null
	and loyalty like 'Lord Voldemort%';
```

### Grupo 2 - Questões - Lógica

**1.** A Batalha de Hogwarts foi uma intensa batalha em que vários bruxos morreram. Esta batalha ocorreu no dia 2 de maio (`2 May`) de 1998. Busque pela quantidade de mortos nesta batalha entre aqueles que lutavam por Albus Dumbledore (`Dumbledore's Army ou Albus Dumbledore`) ou a Ordem da Fênix (`Order of Phoenix`) versus aqueles que lutavam a favor de Lord Voldemort ou eram comensais da morte (`Death Eaters`), inclui-se também o nome `Tom Marvolo Riddle` que é o verdadeiro nome de Lord Voldemort. A resposta deve conter apenas os nomes, as casas e as lealdades.
**Dica:** a busca por `Dumbledore's Army` pode ser feita da seguinte forma `Dumbledore''s Army`, ou seja com duas aspas simples ao pesquisar usando `LIKE` ou `=`.
``` javascript=
select count(*)
from harry_potter
where
	death like '2 May%'
	and (loyalty like '%Dumbledore''s Army%'
		or loyalty like '%Order of the Phoenix%'
		or loyalty like '%Albus Dumbledore%'
		or loyalty like '%Lord Voldemort%'
		or loyalty like '%Death Eaters%'
		or name = 'Tom Marvolo Riddle');
```
**2.** A primeira profecia de Sibila Trelawney é uma famosa profecia que colocou em dúvida quem seria o herói que teria poder para derrotar o grande vilão, Lord Voldemort. Provavelmente os bruxos não tinham um banco de dados tão interessante quanto o nosso, mas a profecia tinha alguns requisitos que curiosamente **alguns** destes podem ser validados pelo dataset.
A profecia dizia que um menino teria as seguintes características:
* Ser do gênero masculino.
* Seus pais tinham desafiado Voldemort três vezes e sobreviveram.
* Ele teria um poder que Voldemort era incapaz ou não queria compreender.
* Nascido nos últimos dias de julho de 1980, ano em que a profecia foi feita (possivelmente 29, 30 ou 31).
* Se mais de uma pessoa nascesse que satisfizer os requisitos, o próprio Voldemort iria escolher a quem acabaria por se referir.

Sua meta é encontrar nomes que poderiam satisfazer nossa vontade de descobrir quem poderia ser o herói.

**Observação:** bom, como dizia o ditado, "*o inimigo do meu inimigo é meu amigo*". Podemos assumir que aliados a Albus Dumbledore, Albus ou a Ordem da Fênix (`Order of the Phoenix`) eram também inimigos de Voldermort. Então isso pode ser um bom indicativo para tentar identificar nosso(s) herói(s).
Com base nesses requisitos quem são os possíveis heróis? A resposta deve conter apenas o nome do bruxo.
``` javascript=
select name
from harry_potter
where
	gender = 'Male'
	and birth like '%1980'
	and birth like '%July%'
	and (loyalty like '%Albus Dumbledore%'
	or loyalty like '%Dumbledore''s Army%'
	or loyalty like '%Order of the Phoenix%');
```
**3.** Busque por todos os trabalhos (`job`), separe-os individualmente e, por fim, ordene-os por quantidade descrecente. Além disso, filtre-os por aqueles que possuem acima de 2. Lembre-se que um personagem pode ter zero ou mais trabalhos e àqueles maiores que 1 são separados por `|` (barra vertical entre espaços). Cuidado: existe uma armadilha nessa pergunta. Na resposta deve existir apenas trabalhos distintos.

``` javascript=
select * from (
	select unnest(string_to_array(job, ' | ')) as trabalhos, count(*)
	from harry_potter
	where job is not null
	group by trabalhos
	order by count(*) desc) as trabalhos
where count > 2;
```
**4.** Busque por todos aqueles que entram nessas restrições:
* Nasceram em Setembro `September` (`birth`).
* Não faleceram (`death`).
* Não possuem nomes iguais àqueles achados na questão 7 (utilize subquery).
* Possuem lealdade associada a alguém (`loyalty`).
* Que seu patrono não seja `Unknown` nem `Non-corporeal`.
* Que possuam alguma casa (`house`).
* Sejam do gênero feminino (`gender`).

A resposta deve conter os nomes das bruxas.

``` javascript=
select name
from harry_potter
where
	gender = 'Female'
	and birth like '%September%'
	and death is null
	and loyalty is not null
	and patronus <> 'Unknown'
	and patronus <> 'Non-corporeal'
	and house is not null
	and name not in (select name
		from harry_potter
		where
			house <> 'Slytherin'
			and house is not null
			and loyalty like 'Lord Voldemort%');
```

### Grupo 3 - Questões - Subqueries e JOIN

**1.** Todas as proposições abaixo PRECISAM ser executadas em uma só consulta, podendo utilizar subconsultas.

**1.A.** Busque por todos os nomes de bruxos e quebre as palavras a fim de encontrarmos cada palavra usada como nome.
``` javascript=
select unnest(string_to_array(name, ' ')) as nomes
from harry_potter;
```
**1.B.** Agora, agrupe os nomes a fim de encontrar a quantidade de vezes que o certo nome é repetido. Lembre-se, existem pessoas com famílias, então espera-se repetição de nomes (que apareçam número maior do que 1).
``` javascript=
select unnest(string_to_array(name, ' ')) as nomes, count(*)
from harry_potter
group by nomes;
```
**1.C.** Ordene-as palavras usadas como nome pela quantidade de repetições.
``` javascript=
select unnest(string_to_array(name, ' ')) as nomes, count(*)
from harry_potter
group by nomes
order by count(*) desc;
```
**1.D.** Filtre por todos aqueles nomes que tiveram 4 ou mais repetições.
``` javascript=
select * from (
	select unnest(string_to_array(name, ' ')) as nomes, count(*)
	from harry_potter
	group by nomes
	order by count(*) desc) as qtd
where count >= 4;
```
**1.E.** Agora, utilizando o recurso de `JOIN`, encontre todos os personagens que possuem nome que esteja no grupo encontrado na questão anterior (**1.D**).
``` javascript=
select 
	tabela.name,
	tabela.house,
	tabela2.nomes
from 
(select name, house, unnest(string_to_array(name, ' ')) as nomes
	from harry_potter) as tabela
inner join
(select * from (
		select unnest(string_to_array(name, ' ')) as nomes, count(*)
		from harry_potter
		group by nomes
		order by count(*) desc) as qtd
	where count >= 4) as tabela2
on tabela.nomes = tabela2.nomes;
```
**1.F.** Agora, filtre apenas por aqueles que estejam vinculados a casa de magia (`house` sejam `IS NOT NULL`).
``` javascript=
select * from (
		select 
		tabela.name,
		tabela.house,
		tabela2.nomes
	from 
	(select name, house, unnest(string_to_array(name, ' ')) as nomes
		from harry_potter) as tabela
	inner join
	(select * from (
			select unnest(string_to_array(name, ' ')) as nomes, count(*)
			from harry_potter
			group by nomes
			order by count(*) desc) as qtd
		where count >= 4) as tabela2
	on tabela.nomes = tabela2.nomes) as selecao
where house is not null;
```
**1.G.** Agora, encontre a quantidade de pessoas por casa de magia (`house`).
``` javascript=
select house, count(*) from(
	select * from (
			select 
			tabela.name,
			tabela.house,
			tabela2.nomes
		from 
		(select name, house, unnest(string_to_array(name, ' ')) as nomes
			from harry_potter) as tabela
		inner join
		(select * from (
				select unnest(string_to_array(name, ' ')) as nomes, count(*)
				from harry_potter
				group by nomes
				order by count(*) desc) as qtd
			where count >= 4) as tabela2
		on tabela.nomes = tabela2.nomes) as selecao
	where house is not null) as contagem
group by house
order by count(*) desc;
```
**2.** Todas proposições abaixo PRECISAM ser executadas em uma só consulta podendo utilizar subconsultas. O quadribol é um esporte bastante popular entre bruxos e existem várias posições muito parecidas com o Futebol ou Volei. No Quadribol, existem o apanhador (`Seeker`), o artilheiro (`Chaser`), o batedor (`Beater`) e até mesmo o goleiro (`Keeper`). A coluna de habilidades (`skills`) listam várias habilidades separadas por `|` (barra vertical entre espaços). Responda as perguntas abaixo com uma única consulta podendo utilizar subqueries:

**2.A.** Entre todas as habilidades, quebre-as e busque por aquelas que falem sobre as posições do Quadribol citadas anteriormente no enunciado.
``` javascript=
select * from (
	select unnest(string_to_array(skills, ' | ')) as habilidades
	from harry_potter) as tabela
where habilidades = 'Seeker'
	or habilidades = 'Chaser'
	or habilidades = 'Beater'
	or habilidades = 'Keeper';
```
**2.B.** Sabendo das informações da questão anterior (**2.A.**), liste a quantidade de jogadores por posição.
``` javascript=
select distinct *, count(*) from (
	select unnest(string_to_array(skills, ' | ')) as habilidades
	from harry_potter) as tabela
where habilidades = 'Seeker'
	or habilidades = 'Chaser'
	or habilidades = 'Beater'
	or habilidades = 'Keeper'
group by habilidades;
```
**2.C** Sabendo das informações da questão anterior (**2.B**), ordene-os os registros encontrados e busque pela posição que possui MENOR quantidade de jogadores.
``` javascript=
select distinct *, count(*) from (
	select unnest(string_to_array(skills, ' | ')) as habilidades
	from harry_potter) as tabela
where habilidades = 'Seeker'
	or habilidades = 'Chaser'
	or habilidades = 'Beater'
	or habilidades = 'Keeper'
group by habilidades
order by
	count(*) asc
	limit 1;
```
**2.D.** Sabendo das informações da questão anterior (**2.C**), busque por todos os jogadores que são da posição encontrada.
``` javascript=
select * from (
	select name, unnest(string_to_array(skills, ' | ')) as habilidades
		from harry_potter) as nomes
	where habilidades in 
	(select habilidades from (
		select distinct habilidades, count(*) from (
			select unnest(string_to_array(skills, ' | ')) as habilidades
			from harry_potter) as tabela1
		where habilidades = 'Seeker'
			or habilidades = 'Chaser'
			or habilidades = 'Beater'
			or habilidades = 'Keeper'
		group by habilidades
		order by
			count(*) asc
			limit 1) as tabela2);
```
**3.** Para aqueles bruxos que possuam patrono e que esses patronos não sejam `Unknown`, `None` e `Non-corporeal` nem `NULL`, busque pelos bruxos ou bruxas que possuem o mesmo animal. Por fim, ordene-os alfabeticamente e traga a informação de nome e o patrono.
``` javascript=
select name, patronus
from harry_potter
where patronus in (
	select patronus from (
		select patronus, count(*)
		from harry_potter
		where
			patronus <> 'Unknown'
			and patronus <> 'None'
			and patronus <> 'Non-corporeal'
			and patronus is not null
		group by patronus) as qtd
	where count > 1)
order by patronus;
```
**4.** Todas as proposições abaixo PRECISAM ser executadas em uma só consulta podendo utilizar subconsultas:

**4.A.** Busque por todas possibilidades individuais de lealdade (`Loyalty`).
**Dica:** os valores estão listados separando cada valor por `|` (barra vertical entre espaços).
``` javascript=
select unnest(string_to_array(loyalty, ' | ')) as lealdades
from harry_potter;
```
**4.B.** Após saber da informação (**4.A**), busque por estas mesmas lealdades e suas respectivas quantidades.
``` javascript=
select unnest(string_to_array(loyalty, ' | ')) as lealdades, count(*)
from harry_potter
group by lealdades
order by count(*) desc;
```
**4.C.** Após saber da informação (**4.B**), busque por aquela lealdade que possui quantidade igual a 4 e que não seja igual ao ministro da magia (`Minister of Magic`).
``` javascript=
select * from (
	select unnest(string_to_array(loyalty, ' | ')) as lealdades, count(*)
	from harry_potter
	group by lealdades
	order by count(*) desc) as selecao
where
	count = 4
	and lealdades <> 'Minister of Magic';
```
**4.D.** Após saber da informação (**4.C**), busque pelo nome das pessoas que possuem lealdade ao indíviduo ou organização encontrada no ponto anterior.
``` javascript=
select name
from 
	(select name, unnest(string_to_array(loyalty, ' | ')) as lealdades
	from harry_potter) as selecao3
inner join
	(select * from (
		select unnest(string_to_array(loyalty, ' | ')) as lealdades, count(*)
		from harry_potter
		group by lealdades
		order by count(*) desc) as selecao
	where
		count = 4
		and lealdades <> 'Minister of Magic') as selecao2
on selecao3.lealdades = selecao2.lealdades;
```