├── .eslintignore ├── .gitattributes ├── .eslintrc.json ├── .gitignore ├── SpotifyClone-Non-NormalizedTable.xlsx ├── jest.config.js ├── desafio9.sql ├── desafio8.sql ├── desafio5.sql ├── desafio6.sql ├── desafio4.sql ├── desafio2.sql ├── desafio3.sql ├── desafio7.sql ├── .editorconfig ├── desafio10.sql ├── README.md ├── desafio1.json ├── desafio11.sql ├── package.json ├── docker-compose.yml └── desafio1.sql /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | tests -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sql linguist-detectable=true -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "trybe-backend" 3 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | 3 | # VSCode repo settings 4 | .vscode 5 | -------------------------------------------------------------------------------- /SpotifyClone-Non-NormalizedTable.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Alexsandro-01/mysql/HEAD/SpotifyClone-Non-NormalizedTable.xlsx -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | verbose: true, 3 | testTimeout: 1000000, 4 | rootDir: './tests', 5 | testSequencer: './assets/sequencer.js', 6 | testRegex: './*\\.spec\\.js$', 7 | }; 8 | -------------------------------------------------------------------------------- /desafio9.sql: -------------------------------------------------------------------------------- 1 | SELECT 2 | COUNT(hst.usuario_id) as quantidade_musicas_no_historico 3 | FROM 4 | historico as hst 5 | INNER JOIN 6 | usuario as usr 7 | ON 8 | hst.usuario_id = usr.id 9 | WHERE 10 | usr.nome LIKE "Bill"; -------------------------------------------------------------------------------- /desafio8.sql: -------------------------------------------------------------------------------- 1 | SELECT 2 | art.nome as artista, 3 | alb.nome as album 4 | FROM 5 | album as alb 6 | INNER JOIN 7 | artista as art 8 | ON 9 | art.id = alb.artista_id 10 | WHERE 11 | art.nome LIKE 'Walter Phoenix' 12 | ORDER BY 13 | album ASC; -------------------------------------------------------------------------------- /desafio5.sql: -------------------------------------------------------------------------------- 1 | SELECT 2 | mus.nome as cancao, 3 | count(hst.musica_id) as reproducoes 4 | FROM 5 | historico as hst 6 | INNER JOIN 7 | musica as mus 8 | ON 9 | mus.id = hst.musica_id 10 | GROUP BY 11 | hst.musica_id 12 | ORDER By 13 | reproducoes DESC, 14 | mus.nome 15 | LIMIT 16 | 2; -------------------------------------------------------------------------------- /desafio6.sql: -------------------------------------------------------------------------------- 1 | SELECT 2 | MIN(pln.valor) as faturamento_minimo, 3 | MAX(pln.valor) as faturamento_maximo, 4 | ROUND(SUM(pln.valor) / COUNT(pln.valor), 2) as faturamento_medio, 5 | SUM(pln.valor) as faturamento_total 6 | FROM 7 | plano as pln 8 | INNER JOIN 9 | usuario as usr 10 | ON 11 | usr.plano_id = pln.id; 12 | -------------------------------------------------------------------------------- /desafio4.sql: -------------------------------------------------------------------------------- 1 | SELECT 2 | usr.nome as usuario, 3 | (CASE 4 | when year(MAX(hst.data_reproducao)) = 2021 then 'Usuário ativo' 5 | else 'Usuário inativo' 6 | END) as condicao_usuario 7 | FROM 8 | usuario as usr 9 | INNER JOIN 10 | historico as hst 11 | ON 12 | hst.usuario_id = usr.id 13 | GROUP BY 14 | usr.nome; 15 | 16 | -------------------------------------------------------------------------------- /desafio2.sql: -------------------------------------------------------------------------------- 1 | SELECT 2 | ( 3 | SELECT 4 | COUNT(*) 5 | FROM 6 | `SpotifyClone`.musica 7 | ) 8 | AS 9 | `cancoes`, 10 | 11 | ( 12 | SELECT 13 | COUNT(*) 14 | FROM 15 | `SpotifyClone`.artista 16 | ) 17 | AS 18 | `artistas`, 19 | 20 | ( 21 | SELECT 22 | COUNT(*) 23 | FROM 24 | `SpotifyClone`.album 25 | ) 26 | AS 27 | `albuns`; 28 | -------------------------------------------------------------------------------- /desafio3.sql: -------------------------------------------------------------------------------- 1 | SELECT 2 | usr.nome as usuario, 3 | count(hst.usuario_id) as qtde_musicas_ouvidas, 4 | ROUND(SUM(mus.duracao) / 60, 2) as total_minutos 5 | FROM 6 | usuario as usr 7 | INNER JOIN 8 | historico as hst 9 | ON 10 | hst.usuario_id = usr.id 11 | INNER JOIN 12 | musica as mus 13 | ON 14 | mus.id = hst.musica_id 15 | GROUP BY 16 | hst.usuario_id 17 | ORDER BY 18 | usr.nome ASC; 19 | -------------------------------------------------------------------------------- /desafio7.sql: -------------------------------------------------------------------------------- 1 | SELECT 2 | art.nome as artista, 3 | alb.nome as album, 4 | COUNT(seg.artista_id) as seguidores 5 | FROM 6 | seguindo as seg 7 | INNER JOIN 8 | album as alb 9 | ON 10 | alb.artista_id = seg.artista_id 11 | INNER JOIN 12 | artista as art 13 | ON 14 | art.id = alb.artista_id 15 | GROUP BY 16 | seg.artista_id, 17 | alb.id 18 | ORDER BY 19 | seguidores DESC, 20 | artista ASC, 21 | album ASC; 22 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | insert_final_newline = true 10 | trim_trailing_whitespace = false 11 | 12 | # Matches multiple files with brace expansion notation 13 | # Set default charset 14 | [*.{js,html,md,css,sql}] 15 | charset = utf-8 16 | indent_style = space 17 | indent_size = 2 18 | -------------------------------------------------------------------------------- /desafio10.sql: -------------------------------------------------------------------------------- 1 | SELECT 2 | msc.nome as nome, 3 | count(hst.musica_id) as reproducoes 4 | FROM 5 | historico as hst 6 | INNER JOIN 7 | usuario as usr 8 | ON 9 | usr.id = hst.usuario_id 10 | INNER JOIN 11 | plano as pln 12 | ON 13 | pln.id = usr.plano_id 14 | INNER JOIN 15 | musica as msc 16 | ON 17 | msc.id = hst.musica_id 18 | WHERE 19 | pln.nome = 'gratuito' OR pln.nome = 'pessoal' 20 | GROUP BY 21 | msc.nome, 22 | hst.musica_id 23 | ORDER BY 24 | msc.nome; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🚧 README em construção 🚧 2 | 11 | -------------------------------------------------------------------------------- /desafio1.json: -------------------------------------------------------------------------------- 1 | { 2 | "coluna_usuario": "nome", 3 | "tabela_que_contem_usuario": "usuario", 4 | "coluna_plano": "nome", 5 | "tabela_que_contem_plano": "plano", 6 | "coluna_historico_de_reproducoes": "musica_id", 7 | "tabela_que_contem_historico_de_reproducoes": "historico", 8 | "coluna_seguindo_artistas": "artista_id", 9 | "tabela_que_contem_seguindo_artistas": "seguindo", 10 | "coluna_artista": "nome", 11 | "tabela_que_contem_artista": "artista", 12 | "coluna_album": "nome", 13 | "tabela_que_contem_album": "album", 14 | "coluna_cancoes": "nome", 15 | "tabela_que_contem_cancoes": "musica" 16 | } -------------------------------------------------------------------------------- /desafio11.sql: -------------------------------------------------------------------------------- 1 | SELECT 2 | nome as nome_musica, 3 | ( 4 | CASE 5 | WHEN nome LIKE '%Streets' THEN REPLACE(nome, 'Streets', 'Code Review') 6 | WHEN nome LIKE '%Her Own' THEN REPLACE(nome, 'Her Own', 'Trybe') 7 | WHEN nome LIKE '%Inner Fire' THEN REPLACE(nome, 'Inner Fire', 'Project') 8 | WHEN nome LIKE '%Silly' THEN REPLACE(nome, 'Silly', 'Nice') 9 | WHEN nome LIKE '%Circus' THEN REPLACE(nome, 'Circus', 'Pull Request') 10 | END 11 | ) as novo_nome 12 | FROM 13 | musica 14 | WHERE 15 | nome LIKE '%Streets' OR 16 | nome LIKE '%Her Own' OR 17 | nome LIKE '%Inner Fire' OR 18 | nome LIKE '%Silly' OR 19 | nome LIKE '%Circus' 20 | ORDER BY 21 | nome; 22 | 23 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sd-0x-mysql-one-for-all", 3 | "version": "1.0.0", 4 | "description": "Project MySQL One For All", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "jest --runInBand --verbose --forceExit", 8 | "test:watch": "jest --watchAll", 9 | "lint": "eslint --no-inline-config --no-error-on-unmatched-pattern -c .eslintrc.json . --ext .js, .jsx" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/betrybe/sd-0x-mysql-one-for-all.git" 14 | }, 15 | "keywords": [ 16 | "javascript", 17 | "tests", 18 | "assert", 19 | "jest" 20 | ], 21 | "author": "Trybe", 22 | "license": "ISC", 23 | "bugs": { 24 | "url": "https://github.com/betrybe/sd-0x-mysql-one-for-all/issues" 25 | }, 26 | "homepage": "https://github.com/betrybe/sd-0x-mysql-one-for-all#readme", 27 | "devDependencies": { 28 | "acorn": "5.7.4", 29 | "jest": "24.9.0", 30 | "minimist": "1.2.2", 31 | "mysql-import": "4.0.24" 32 | }, 33 | "dependencies": { 34 | "eslint-config-trybe-backend": "^1.0.4", 35 | "mysql2": "2.1.0", 36 | "sequelize": "6.2.0" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | # Serviço que irá rodar o node 5 | node: 6 | # Imagem base do container 7 | image: node:16 8 | # Nome do container para facilitar execução 9 | container_name: one_for_all 10 | # Mesmo que `docker run -t` 11 | tty: true 12 | # Mesmo que `docker run -i` 13 | stdin_open: true 14 | # Substitui o comando padrão da imagem do node 15 | command: bash 16 | # Restarta a imagem caso algo a faça parar 17 | restart: always 18 | # Diretório padrão de execução 19 | working_dir: /app 20 | # Lista de volumes (diretórios) mapeados de fora para dentro do container 21 | volumes: 22 | # Monta o diretório atual, com todos os dados do projeto, 23 | # dentro do diretório /app 24 | - ./:/app 25 | # Lista de serviços do qual este serviço depende 26 | depends_on: 27 | # Precisa do banco funcionando antes de subir o node 28 | - db 29 | # Configura as variáveis de ambiente dentro do container 30 | environment: 31 | MYSQL_USER: root 32 | MYSQL_PASSWORD: password 33 | HOSTNAME: db 34 | 35 | # Serviço que irá rodar o banco de dados 36 | db: 37 | container_name: one_for_all_db 38 | image: mysql:5.7 39 | restart: always 40 | # Lista de portas mapeadas de dentro para fora do container 41 | # na notação porta_de_fora:porta_de_dentro 42 | ports: 43 | # Expõe a porta padrão do banco de dados 44 | - 3306:3306 45 | environment: 46 | MYSQL_ROOT_PASSWORD: password 47 | 48 | # Lista de redes que os containeres irão utilizar 49 | networks: 50 | # Rede padrão, criada automaticamente 51 | default: 52 | # Dá um nome específico à rede padrão 53 | name: one_for_all_net 54 | 55 | # As chaves `tty`, `stdin_open` e `command` fazem com que o container fique 56 | # rodando em segundo plano, bem como tornam possível o uso do comando 57 | # `docker attach`, já deixando o terminal atual acoplado ao container, direto 58 | # no bash. Apesar disso, utilizar o attach mais de uma vez irá replicar o 59 | # terminal, portanto é melhor utilizar o comando `docker exec`. 60 | 61 | # A renomeação da rede padrão é feita pois caso contrário o nome da rede será 62 | # o nome do diretório onde o arquivo atual se encontra, o que pode dificultar 63 | # a listagem individual. 64 | -------------------------------------------------------------------------------- /desafio1.sql: -------------------------------------------------------------------------------- 1 | DROP DATABASE IF EXISTS SpotifyClone; 2 | 3 | CREATE DATABASE SpotifyClone; 4 | 5 | CREATE TABLE SpotifyClone.plano( 6 | id INT NOT NULL AUTO_INCREMENT, 7 | nome VARCHAR(20) NOT NULL, 8 | valor DECIMAL(5,2) NOT NULL, 9 | PRIMARY KEY (id) 10 | ); 11 | 12 | CREATE Table SpotifyClone.usuario( 13 | id INT NOT NULL AUTO_INCREMENT, 14 | nome VARCHAR(50) NOT NULL, 15 | idade INT NOT NULL, 16 | plano_id INT NOT NULL, 17 | data_assinatura DATE NOT NULL, 18 | FOREIGN KEY (plano_id) REFERENCES plano (id), 19 | PRIMARY KEY (id) 20 | ); 21 | 22 | CREATE Table SpotifyClone.artista( 23 | id INT NOT NULL AUTO_INCREMENT, 24 | nome VARCHAR(50), 25 | PRIMARY KEY (id) 26 | ); 27 | 28 | CREATE Table SpotifyClone.seguindo( 29 | usuario_id INT NOT NULL, 30 | artista_id INT NOT NULL, 31 | PRIMARY KEY (usuario_id, artista_id), 32 | FOREIGN KEY (usuario_id) REFERENCES usuario (id), 33 | FOREIGN KEY (artista_id) REFERENCES artista (id) 34 | ); 35 | 36 | CREATE Table SpotifyClone.album( 37 | id INT NOT NULL AUTO_INCREMENT, 38 | nome VARCHAR(50) NOT NULL, 39 | artista_id INT NOT NULL, 40 | ano_lancamento YEAR(4) NOT NULL, 41 | PRIMARY KEY (id), 42 | FOREIGN KEY (artista_id) REFERENCES artista (id) 43 | ); 44 | 45 | CREATE Table SpotifyClone.musica( 46 | id INT NOT NULL AUTO_INCREMENT, 47 | nome VARCHAR(50) NOT NULL, 48 | duracao INT NOT NULL, 49 | album_id INT NOT NULL, 50 | FOREIGN KEY (album_id) REFERENCES album (id), 51 | PRIMARY KEY (id) 52 | ); 53 | 54 | CREATE Table SpotifyClone.historico( 55 | usuario_id INT NOT NULL, 56 | musica_id INT NOT NULL, 57 | data_reproducao TIMESTAMP NOT NULL, 58 | PRIMARY KEY (usuario_id, musica_id), 59 | FOREIGN KEY (usuario_id) REFERENCES usuario (id), 60 | FOREIGN KEY (musica_id) REFERENCES musica (id) 61 | ); 62 | 63 | INSERT INTO SpotifyClone.plano( 64 | nome, valor 65 | ) 66 | VALUES 67 | ("gratuito", 0), 68 | ("familiar", 7.99), 69 | ("universitário", 5.99), 70 | ("pessoal", 6.99); 71 | 72 | INSERT INTO 73 | SpotifyClone.usuario( 74 | nome, idade, plano_id, data_assinatura 75 | ) 76 | VALUES 77 | ("Thati", 23, 1, "2019-10-20"), 78 | ("Cintia", 35, 2, "2017-12-30"), 79 | ("Bill", 20, 3, "2019-06-05"), 80 | ("Roger", 45, 4, "2020-05-13"), 81 | ("Norman", 58, 4, "2017-02-17"), 82 | ("Patrick", 33, 2, "2017-01-06"), 83 | ("Vivian", 26, 3, "2018-01-05"), 84 | ("Carol", 19, 3, "2018-02-14"), 85 | ("Angelina", 42, 2, "2018-04-29"), 86 | ("Paul", 46, 2, "2017-01-17"); 87 | 88 | INSERT INTO 89 | SpotifyClone.artista( 90 | nome 91 | ) 92 | VALUES 93 | ("Walter Phoenix"), 94 | ("Peter Strong"), 95 | ("Lance Day"), 96 | ("Freedie Shannon"), 97 | ("Tyler Isle"), 98 | ("Fog"); 99 | 100 | INSERT INTO 101 | `SpotifyClone`.seguindo( 102 | usuario_id, artista_id 103 | ) 104 | VALUES 105 | (1, 1), 106 | (1, 4), 107 | (1, 3), 108 | (2, 1), 109 | (2, 3), 110 | (3, 2), 111 | (3, 1), 112 | (4, 4), 113 | (5, 5), 114 | (5, 6), 115 | (6, 6), 116 | (6, 3), 117 | (6, 1), 118 | (7, 2), 119 | (7, 5), 120 | (8, 1), 121 | (8, 5), 122 | (9, 6), 123 | (9, 4), 124 | (9, 3), 125 | (10, 2), 126 | (10, 6); 127 | 128 | INSERT INTO 129 | `SpotifyClone`.album( 130 | nome, artista_id, ano_lancamento 131 | ) 132 | VALUES 133 | ("Envious", 1, "1990"), 134 | ("Exuberant", 1, "1993"), 135 | ("Hallowed Steam", 2, "1995"), 136 | ("Incandescent", 3, "1998"), 137 | ("Temporary Culture", 4, "2001"), 138 | ("Library of liberty", 4, "2003"), 139 | ("Chained Down", 5, "2007"), 140 | ("Cabinet of fools", 5, "2012"), 141 | ("No guarantees", 5, "2015"), 142 | ("Apparatus", 6, "2015"); 143 | 144 | INSERT INTO 145 | `SpotifyClone`.musica( 146 | nome, duracao, album_id 147 | ) 148 | VALUES 149 | ("Soul For Us", 200, 1), 150 | ("Reflections Of Magic", 163, 1), 151 | ("Dance With Her Own", 116, 1), 152 | ("Troubles Of My Inner Fire", 203, 2), 153 | ("Time Fireworks", 152, 2), 154 | ("Magic Circus", 105, 3), 155 | ("Honey, So Do I", 207, 3), 156 | ("Sweetie, Let's Go Wild", 139, 3), 157 | ("She Knows", 244, 3), 158 | ("Fantasy For Me", 100, 4), 159 | ("Celebration Of More", 146, 4), 160 | ("Rock His Everything", 223, 4), 161 | ("Home Forever", 231, 4), 162 | ("Diamond Power", 241, 4), 163 | ("Let's Be Silly", 132, 4), 164 | ("Thang Of Thunder", 240, 5), 165 | ("Words Of Her Life", 185, 5), 166 | ("Without My Streets", 176, 5), 167 | ("Need Of The Evening", 190, 6), 168 | ("History Of My Roses", 222, 6), 169 | ("Without My Love", 111, 6), 170 | ("Walking And Game", 123, 6), 171 | ("Young And Father", 197, 6), 172 | ("Finding My Traditions", 179, 7), 173 | ("Walking And Man", 229, 7), 174 | ("Hard And Time", 135, 7), 175 | ("Honey, I'm A Lone Wolf", 150, 7), 176 | ("She Thinks I Won't Stay Tonight", 166, 8), 177 | ("He Heard You're Bad For Me", 154, 8), 178 | ("He Hopes We Can't Stay", 210, 8), 179 | ("I Know I Know", 117, 8), 180 | ("He's Walking Away", 159, 9), 181 | ("He's Trouble", 138, 9), 182 | ("I Heard I Want To Bo Alone", 120, 9), 183 | ("I Ride Alone", 151, 9), 184 | ("Honey", 79, 10), 185 | ("You Cheated On Me", 95, 10), 186 | ("Wouldn't It Be Nice", 213, 10), 187 | ("Baby", 136, 10), 188 | ("You Make Me Feel So..", 83, 10); 189 | 190 | INSERT INTO 191 | `SpotifyClone`.historico( 192 | usuario_id, musica_id, data_reproducao 193 | ) 194 | VALUES 195 | (1, 36, "2020-02-28 10:45:55"), 196 | (1, 25, "2020-05-02 05:30:35"), 197 | (1, 23, "2020-03-06 11:22:33"), 198 | (1, 14, "2020-08-05 08:05:17"), 199 | (1, 15, "2020-09-14 16:32:22"), 200 | (2, 34, "2020-01-02 07:40:33"), 201 | (2, 24, "2020-05-16 06:16:22"), 202 | (2, 21, "2020-10-09 12:27:48"), 203 | (2, 39, "2020-09-21 13:14:46"), 204 | (3, 6, "2020-11-13 16:55:13"), 205 | (3, 3, "2020-12-05 18:38:30"), 206 | (3, 26, "2020-07-30 10:00:00"), 207 | (4, 2, "2021-08-15 17:10:10"), 208 | (4, 35, "2021-07-10 15:20:30"), 209 | (4, 27, "2021-01-09 01:44:33"), 210 | (5, 7, "2020-07-03 19:33:28"), 211 | (5, 12, "2017-02-24 21:14:22"), 212 | (5, 14, "2020-08-06 15:23:43"), 213 | (5, 1, "2020-11-10 13:52:27"), 214 | (6, 38, "2019-02-07 20:33:48"), 215 | (6, 29, "2017-01-24 00:31:17"), 216 | (6, 30, "2017-10-12 12:35:20"), 217 | (6, 22, "2018-05-29 14:56:41"), 218 | (7, 5, "2018-05-09 22:30:49"), 219 | (7, 4, "2020-07-27 12:52:58"), 220 | (7, 11, "2018-01-16 18:40:43"), 221 | (8, 39, "2018-03-21 16:56:40"), 222 | (8, 40, "2020-10-18 13:38:05"), 223 | (8, 32, "2019-05-25 08:14:03"), 224 | (8, 33, "2021-08-15 21:37:09"), 225 | (9, 16, "2021-05-24 17:23:45"), 226 | (9, 17, "2018-12-07 22:48:52"), 227 | (9, 8, "2021-03-14 06:14:26"), 228 | (9, 9, "2020-04-01 03:36:00"), 229 | (10, 20, "2017-02-06 08:21:34"), 230 | (10, 21, "2017-12-04 05:33:43"), 231 | (10, 12, "2017-07-27 05:24:49"), 232 | (10, 13, "2017-12-25 01:03:57"); --------------------------------------------------------------------------------