├── 01. Databases Introduction ├── 00. Database-Basics-MySQL-Course-Introduction-Presentation.pdf ├── 01. Database-Basics-MySQL-Introduction-to-Databases-HeidiSQL-On-Linux-Installation-Guidelines.docx ├── 01. Database-Basics-MySQL-Introduction-to-Databases-Presentation.pdf └── 01. Introduction-to-Databases-Exercises.docx ├── 02. Data Definition and Datatypes ├── 02. Database-Basics-MySQL-Data-Definition-And-Datatypes-Exercises.docx ├── 02. Database-Basics-MySQL-Data-Definition-And-Datatypes-Lab.docx ├── 02. Database-Basics-MySQL-Data-Definition-And-Datatypes-Presentation.pdf ├── Data Definition and Datatypes Exercise.sql └── Data Definition and Datatypes Lab.sql ├── 03. Basic CRUD ├── 03. Database-Basics-MySQL-Basic-CRUD-Exercises.docx ├── 03. Database-Basics-MySQL-Basic-CRUD-Lab.docx ├── 03. Database-Basics-MySQL-Basic-CRUD-Presentation.pdf ├── Basic CRUD Exercise.sql ├── Basic CRUD Lab.sql └── Databases │ ├── diablo_database.sql │ ├── geography_database.sql │ ├── hospital.sql │ └── soft_uni_database.sql ├── 04. Built-in Functions ├── 04. Built-in-Functions-Exercises.docx ├── 04. Built-in-Functions-Lab.docx.docx ├── 04. Built-in-Functions.pdf ├── Built-in Functions Exercises.sql ├── Built-in Functions Lab.sql └── Databases │ ├── Chinook_MySql_AutoIncrementPKs.sql │ ├── DemoBD20170125.sql │ ├── Orders-Database.sql │ └── booklibrary.sql ├── 05. Data Aggregation ├── 05. Data-Aggregation-Exercises.docx ├── 05. Data-Aggregation-Lab.docx ├── 05. Data-Aggregation.pdf ├── Data Aggregation Exercises.sql ├── Data Aggregation Lab.sql └── Databases │ ├── gringotts-database.sql │ ├── restaurant.sql │ └── soft_uni_database.sql ├── 06. Table Relations ├── 06. Table-Relations-Exercises.docx ├── 06. Table-Relations-Lab.docx ├── 06. Table-Relations.pdf ├── Databases │ ├── camp.sql │ ├── geography_database.sql │ ├── joins_db.sql │ └── soft_uni_database.sql ├── Table Relations Exercise.sql └── Table Relations Lab.sql ├── 07. Subqueries And Joins ├── 07. Joins, Subqueries and Indices-Lab.docx ├── 07. Joins-Subqueries-and-Indices-Exercise.docx ├── 07. Joins-Subqueries-and-Indices.pdf ├── Databases │ ├── bank_db.sql │ ├── geography_database.sql │ └── soft_uni_database.sql ├── Subqueries And Joins Exercise.sql └── Subqueries And Joins Lab.sql ├── 08. Functions, Triggers and Transactions ├── 08. Functions-Triggers-And-Transactions-Exercise.docx ├── 08. Functions-Triggers-And-Transactions-Lab.docx ├── 08. Functions-Triggers-And-Transactions.pdf ├── Databases │ ├── bank_db.sql │ └── soft_uni_database.sql ├── Functions, Triggers and Transactions Exercise.sql └── Functions, Triggers and Transactions Lab.sql ├── 09. Exam Preparation 1 ├── 01. DDL - Table Design.docx ├── 01. DDL - Table Design_Data Set.sql └── Databases MySQL Exam - 22 Oct 2017.sql ├── 10. Exam Preparation 2 ├── 00. Login_Tables.sql ├── 01. Table Design.docx ├── 01. Table Design_Data.sql └── Databases MySQL Exam - 24 Jun 2017.sql ├── 11. Exam Preparation 3 ├── Bank Skeleton.sql ├── Databases MySQL Exam - 12 Oct 2016.sql └── Sample-Exam-Bank-12-October-2016.docx ├── 12. Exam ├── 01. Table Design.docx ├── Database MySQL Exam - 25 February 2018.sql ├── Reset Database Wth Values.sql └── dataset-2.sql └── README.md /01. Databases Introduction/00. Database-Basics-MySQL-Course-Introduction-Presentation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/01. Databases Introduction/00. Database-Basics-MySQL-Course-Introduction-Presentation.pdf -------------------------------------------------------------------------------- /01. Databases Introduction/01. Database-Basics-MySQL-Introduction-to-Databases-HeidiSQL-On-Linux-Installation-Guidelines.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/01. Databases Introduction/01. Database-Basics-MySQL-Introduction-to-Databases-HeidiSQL-On-Linux-Installation-Guidelines.docx -------------------------------------------------------------------------------- /01. Databases Introduction/01. Database-Basics-MySQL-Introduction-to-Databases-Presentation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/01. Databases Introduction/01. Database-Basics-MySQL-Introduction-to-Databases-Presentation.pdf -------------------------------------------------------------------------------- /01. Databases Introduction/01. Introduction-to-Databases-Exercises.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/01. Databases Introduction/01. Introduction-to-Databases-Exercises.docx -------------------------------------------------------------------------------- /02. Data Definition and Datatypes/02. Database-Basics-MySQL-Data-Definition-And-Datatypes-Exercises.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/02. Data Definition and Datatypes/02. Database-Basics-MySQL-Data-Definition-And-Datatypes-Exercises.docx -------------------------------------------------------------------------------- /02. Data Definition and Datatypes/02. Database-Basics-MySQL-Data-Definition-And-Datatypes-Lab.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/02. Data Definition and Datatypes/02. Database-Basics-MySQL-Data-Definition-And-Datatypes-Lab.docx -------------------------------------------------------------------------------- /02. Data Definition and Datatypes/02. Database-Basics-MySQL-Data-Definition-And-Datatypes-Presentation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/02. Data Definition and Datatypes/02. Database-Basics-MySQL-Data-Definition-And-Datatypes-Presentation.pdf -------------------------------------------------------------------------------- /02. Data Definition and Datatypes/Data Definition and Datatypes Lab.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE IF NOT EXISTS `gamebar`; 2 | USE `gamebar`; 3 | 4 | CREATE TABLE `employees` ( 5 | `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, 6 | `first_name` VARCHAR(50) NOT NULL, 7 | `last_name` VARCHAR(50) NOT NULL, 8 | PRIMARY KEY (`id`) 9 | ) 10 | COLLATE='utf8_general_ci' 11 | ENGINE=InnoDB 12 | ; 13 | 14 | CREATE TABLE `categories` ( 15 | `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, 16 | `name` VARCHAR(50) NOT NULL, 17 | PRIMARY KEY (`id`) 18 | ) 19 | COLLATE='utf8_general_ci' 20 | ENGINE=InnoDB 21 | ; 22 | 23 | CREATE TABLE `products` ( 24 | `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, 25 | `name` VARCHAR(50) NOT NULL, 26 | `category_id` INT(11) UNSIGNED NOT NULL, 27 | PRIMARY KEY (`id`), 28 | KEY `FK_products_categories` (`category_id`), 29 | CONSTRAINT `FK_products_categories` FOREIGN KEY (category_id) 30 | REFERENCES `categories` (`id`) 31 | ) 32 | COLLATE='utf8_general_ci'employees 33 | ENGINE=InnoDB 34 | ; 35 | 36 | INSERT INTO `gamebar`.`employees` (`first_name`, `last_name`) 37 | VALUES ("Pesho", "Petrov"), ("Ivan", "Ivanov"), ("Georgy", "Georgiev"); 38 | 39 | ALTER TABLE `gamebar`.`employees` ADD COLUMN `middle_name` VARCHAR(50) NOT NULL DEFAULT ""; 40 | 41 | ALTER TABLE `gamebar`.`employees` MODIFY COLUMN `middle_name` VARCHAR(100) NOT NULL; 42 | 43 | DROP DATABASE `gamebar`; -------------------------------------------------------------------------------- /03. Basic CRUD/03. Database-Basics-MySQL-Basic-CRUD-Exercises.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/03. Basic CRUD/03. Database-Basics-MySQL-Basic-CRUD-Exercises.docx -------------------------------------------------------------------------------- /03. Basic CRUD/03. Database-Basics-MySQL-Basic-CRUD-Lab.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/03. Basic CRUD/03. Database-Basics-MySQL-Basic-CRUD-Lab.docx -------------------------------------------------------------------------------- /03. Basic CRUD/03. Database-Basics-MySQL-Basic-CRUD-Presentation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/03. Basic CRUD/03. Database-Basics-MySQL-Basic-CRUD-Presentation.pdf -------------------------------------------------------------------------------- /03. Basic CRUD/Basic CRUD Exercise.sql: -------------------------------------------------------------------------------- 1 | -- Download and get familiar with the soft_uni, diablo and geography 2 | -- database schemas and tables. You will use them in this and the 3 | -- following exercises to write queries. 4 | 5 | -- Part I – Queries for SoftUni Database 6 | 7 | USE `soft_uni`; 8 | 9 | -- 02. Find All Information About Departments 10 | -- Write a SQL query to find all available information about the departments. 11 | -- Sort the information by id. 12 | 13 | SELECT 14 | * 15 | FROM 16 | `departments` 17 | ORDER BY `department_id`; 18 | 19 | -- 03. Find all Department Names 20 | -- Write SQL query to find all department names. Sort the information by id. 21 | 22 | SELECT 23 | `name` 24 | FROM 25 | `departments` 26 | ORDER BY `department_id`; 27 | 28 | -- 04. Find Salary of Each Employee 29 | -- Write SQL query to find the first name, last name and salary of each employee. 30 | -- Sort the information by id. 31 | 32 | SELECT 33 | `first_name`, `last_name`, `salary` 34 | FROM 35 | `employees` 36 | ORDER BY `employee_id`; 37 | 38 | -- 05. Find Full Name of Each Employee 39 | -- Write SQL query to find the first, middle and last name of each employee. 40 | -- Sort the information by id. 41 | 42 | SELECT 43 | `first_name`, `middle_name`, `last_name` 44 | FROM 45 | `employees` 46 | ORDER BY `employee_id`; 47 | 48 | -- 06. Find Email Address of Each Employee 49 | -- Write a SQL query to find the email address of each employee. 50 | -- (by his first and last name). Consider that the email domain is softuni.bg. 51 | -- Emails should look like “John.Doe@softuni.bg". The produced column should 52 | -- be named "full_ email_address". 53 | 54 | SELECT 55 | CONCAT(`first_name`, 56 | '.', 57 | `last_name`, 58 | '@softuni.bg') AS 'full_ email_address' 59 | FROM 60 | `employees`; 61 | 62 | -- 07. Find All Different Employee’s Salaries 63 | -- Write a SQL query to find all different employee’s salaries. 64 | -- Show only the salaries. Sort the information by id 65 | 66 | SELECT DISTINCT 67 | `salary` 68 | FROM 69 | `employees` 70 | ORDER BY `employee_id`; 71 | 72 | -- 08. Find all Information About Employees 73 | -- Write a SQL query to find all information about the employees 74 | -- whose job title is “Sales Representative”. Sort the information by id. 75 | 76 | SELECT 77 | * 78 | FROM 79 | `employees` 80 | WHERE 81 | `job_title` = 'Sales Representative' 82 | ORDER BY `employee_id`; 83 | 84 | -- 09. Find Names of All Employees by Salary in Range 85 | -- Write a SQL query to find the first name, last name and job title of all 86 | -- employees whose salary is in the range [20000, 30000]. Sort the information by id. 87 | 88 | SELECT 89 | `first_name`, `last_name`, `job_title` 90 | FROM 91 | `employees` 92 | WHERE 93 | `salary` >= 20000.00 94 | AND `salary` <= 30000.00 95 | ORDER BY `employee_id`; 96 | 97 | -- 10. Find Names of All Employees 98 | -- Write a SQL query to find the full name of all employees whose salary 99 | -- is 25000, 14000, 12500 or 23600. Full Name is combination of first, 100 | -- middle and last name (separated with single space) and they should be 101 | -- in one column called “Full Name”. 102 | 103 | SELECT 104 | CONCAT_WS(' ', 105 | `first_name`, 106 | `middle_name`, 107 | `last_name`) AS 'Full Name' 108 | FROM 109 | `employees` 110 | WHERE 111 | `salary` IN (25000.0 , 14000.0, 12500.0, 23600.0); 112 | 113 | -- 11. Find All Employees Without Manager 114 | -- Write a SQL query to find first and last names 115 | -- about those employees that does not have a manager. 116 | 117 | SELECT 118 | `first_name`, `last_name` 119 | FROM 120 | `employees` 121 | WHERE 122 | `manager_id` IS NULL; 123 | 124 | -- 12. Find All Employees with Salary More Than 50000 125 | -- Write a SQL query to find first name, last name and salary of 126 | -- those employees who has salary more than 50000. 127 | -- Order them in decreasing order by salary. 128 | 129 | SELECT 130 | `first_name`, `last_name`, `salary` 131 | FROM 132 | `employees` 133 | WHERE 134 | `salary` > 50000.00 135 | ORDER BY `salary` DESC; 136 | 137 | -- 13. Find 5 Best Paid Employees 138 | -- Write SQL query to find first and last names about 5 best 139 | -- paid Employees ordered descending by their salary. 140 | 141 | SELECT 142 | `first_name`, `last_name` 143 | FROM 144 | `employees` 145 | ORDER BY `salary` DESC 146 | LIMIT 5; 147 | 148 | -- 14. Find All Employees Except Marketing 149 | -- Write a SQL query to find the first and last names of all 150 | -- employees whose department ID is different from 4. 151 | 152 | SELECT 153 | `first_name`, `last_name` 154 | FROM 155 | `employees` 156 | WHERE 157 | `department_id` != 4; 158 | 159 | -- 15. Sort Employees Table 160 | -- Write a SQL query to sort all records in the еmployees table by the following criteria: 161 | -- * First by salary in decreasing order 162 | -- * Then by first name alphabetically 163 | -- * Then by last name descending 164 | -- * Then by middle name alphabetically 165 | -- Sort the information by id. 166 | 167 | SELECT 168 | * 169 | FROM 170 | `employees` 171 | ORDER BY `salary` DESC , `first_name` , `last_name` DESC , `middle_name` , `employee_id`; 172 | 173 | -- 16. Create View Employees with Salaries 174 | -- Write a SQL query to create a view v_employees_salaries with 175 | -- first name, last name and salary for each employee. 176 | 177 | CREATE VIEW `v_employees_salaries` AS 178 | SELECT 179 | `first_name`, `last_name`, `salary` 180 | FROM 181 | `employees`; 182 | 183 | -- 17. Create View Employees with Job Titles 184 | -- Write a SQL query to create view v_employees_job_titles with full employee name 185 | -- and job title. When middle name is NULL replace it with empty string (‘’). 186 | 187 | CREATE VIEW `v_employees_job_titles` AS 188 | SELECT 189 | CONCAT(`first_name`, 190 | ' ', 191 | IFNULL(`middle_name`, ''), 192 | ' ', 193 | `last_name`) AS 'full_name', 194 | `job_title` 195 | FROM 196 | `employees`; 197 | 198 | -- 18. Distinct Job Titles 199 | -- Write a SQL query to find all distinct job titles 200 | -- Order alphabetically by job title 201 | 202 | SELECT DISTINCT 203 | `job_title` 204 | FROM 205 | `employees` 206 | ORDER BY `job_title`; 207 | 208 | -- 19. Find First 10 Started Projects 209 | -- Write a SQL query to find first 10 started projects. 210 | -- Select all information about them and sort them by 211 | -- start date, then by name. Sort the information by id. 212 | 213 | SELECT 214 | * 215 | FROM 216 | `projects` 217 | ORDER BY `start_date` , `name` , `project_id` 218 | LIMIT 10; 219 | 220 | -- 20. Last 7 Hired Employees 221 | -- Write a SQL query to find last 7 hired employees. 222 | -- Select their first, last name and their hire date. 223 | 224 | SELECT 225 | `first_name`, `last_name`, `hire_date` 226 | FROM 227 | `employees` 228 | ORDER BY `hire_date` DESC 229 | LIMIT 7; 230 | 231 | -- 21. Increase Salaries 232 | -- Write a SQL query to increase salaries of all employees 233 | -- that are in the Engineering, Tool Design, Marketing or 234 | -- Information Services department by 12%. Then select 235 | -- Salaries column from the Employees table. 236 | 237 | UPDATE `employees` 238 | SET 239 | `salary` = `salary` * 1.12 240 | WHERE 241 | `department_id` IN (1 , 2, 4, 11); 242 | 243 | SELECT 244 | `salary` 245 | FROM 246 | `employees`; 247 | 248 | 249 | -- Solution with JOIN (doesn't pass tests n Judge!) 250 | 251 | SET SQL_SAFE_UPDATES=0; 252 | UPDATE `employees` AS e 253 | INNER JOIN 254 | `departments` AS d ON d.`department_id` = e.`department_id` 255 | SET 256 | e.`salary` = e.`salary` * 1.12 257 | WHERE 258 | d.`name` IN ('Engineering' , 'Tool Design', 259 | 'Marketing', 260 | 'Information Services'); 261 | SET SQL_SAFE_UPDATES=1; 262 | 263 | SELECT 264 | e.`employee_id`, e.`salary`, d.`name` 265 | FROM 266 | `employees` e 267 | INNER JOIN 268 | `departments` d ON e.`department_id` = d.`department_id` 269 | WHERE 270 | d.`name` IN ('Engineering' , 'Tool Design', 271 | 'Marketing', 272 | 'Information Services'); 273 | 274 | -- Part II – Queries for Geography Database 275 | 276 | USE `geography`; 277 | 278 | -- 22. All Mountain Peaks 279 | -- Display all mountain peaks in alphabetical order. 280 | 281 | SELECT 282 | `peak_name` 283 | FROM 284 | `peaks` 285 | ORDER BY `peak_name`; 286 | 287 | -- 23. Biggest Countries by Population 288 | -- Find the 30 biggest countries by population from Europe. 289 | -- Display the country name and population. Sort the results by 290 | -- population (from biggest to smallest), then by country alphabetically. 291 | 292 | SELECT 293 | `country_name`, `population` 294 | FROM 295 | `countries` 296 | WHERE 297 | `continent_code` = 'EU' 298 | ORDER BY `population` DESC, `country_name` 299 | LIMIT 30; 300 | 301 | -- 24. Countries and Currency (Euro / Not Euro) 302 | -- Find all countries along with information about their currency. 303 | -- Display the country name, country code and information about its 304 | -- currency: either "Euro" or "Not Euro". 305 | -- Sort the results by country name alphabetically. 306 | 307 | SELECT 308 | `country_name`, 309 | `country_code`, 310 | IF(`currency_code` = 'EUR', 311 | 'Euro', 312 | 'Not Euro') AS 'currency' 313 | FROM 314 | `countries` 315 | ORDER BY `country_name`; 316 | 317 | 318 | -- Part III – Queries for Diablo Database 319 | 320 | USE `diablo`; 321 | 322 | -- 25. All Diablo Characters 323 | -- Display all characters in alphabetical order. 324 | 325 | SELECT 326 | `name` 327 | FROM 328 | `characters` 329 | ORDER BY `name`; -------------------------------------------------------------------------------- /03. Basic CRUD/Basic CRUD Lab.sql: -------------------------------------------------------------------------------- 1 | USE `hospital`; 2 | 3 | -- Problem 1: Select Employee Information 4 | -- Write a query to select all employees and retrieve information about 5 | -- their id, first_name, last_name and job_title ordered by id. 6 | SELECT 7 | `id`, `first_name`, `last_name`, `job_title` 8 | FROM 9 | `employees` 10 | ORDER BY `id` ASC; 11 | 12 | -- Problem 2: Select Employees with Filter 13 | -- Write a query to select all employees (id, first_name, last_name, job_title, salary) 14 | -- whose salaries are higher than 1000.00, ordered by id. Concatenate fields first_name 15 | -- and last_name into ‘full_name’. 16 | 17 | SELECT 18 | `id`, 19 | CONCAT(`first_name`, ' ', `last_name`) AS 'full_name', 20 | `job_title`, 21 | `salary` 22 | FROM 23 | `employees` 24 | WHERE 25 | `salary` > 1000.00 26 | ORDER BY `id` ASC; 27 | 28 | -- Problem 3: Update Employees Salary 29 | -- Update all employees salaries whose job_title is “Therapist” by 10%. 30 | -- Retrieve information about all salaries ordered ascending. 31 | 32 | UPDATE `employees` 33 | SET `salary` = `salary` * 1.1 34 | WHERE `job_title` = 'Therapist'; 35 | 36 | SELECT `salary` 37 | FROM `employees` 38 | ORDER BY `salary` ASC; 39 | 40 | -- Problem 4: Top Paid Employee 41 | -- Write a query to create a view that selects all information about the 42 | -- top paid employee from the “employees” table in the hospital database. 43 | 44 | SELECT * FROM `employees` 45 | ORDER BY `salary` DESC 46 | LIMIT 1; 47 | 48 | -- Problem 5: Select Employees by Multiple Filters 49 | -- Write a query to retrieve information about employees, who are in department 50 | -- 4 and have salary higher or equal to 1600. Order the information by id. 51 | 52 | SELECT * FROM `employees` 53 | WHERE (`department_id` = 4 AND `salary` >= 1600.0) 54 | ORDER BY `id`; 55 | 56 | -- Problem 6: Delete from Table 57 | -- Write a query to delete all employees from the “employees” table who are 58 | -- in department 2 or 1. Order the information by id. 59 | 60 | DELETE FROM `employees` 61 | WHERE `department_id` IN (2, 1); 62 | 63 | SELECT * 64 | FROM `employees` 65 | ORDER BY `id` ASC; 66 | -------------------------------------------------------------------------------- /03. Basic CRUD/Databases/hospital.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE IF NOT EXISTS `hospital`; 2 | USE `hospital`; 3 | 4 | CREATE TABLE departments ( 5 | id INT PRIMARY KEY AUTO_INCREMENT, 6 | name VARCHAR(50) 7 | ); 8 | 9 | INSERT INTO departments(name) VALUES('Therapy'), ('Support'), ('Management'), ('Other'); 10 | 11 | CREATE TABLE employees ( 12 | id INT PRIMARY KEY AUTO_INCREMENT, 13 | first_name VARCHAR(50) NOT NULL, 14 | last_name VARCHAR(50) NOT NULL, 15 | job_title VARCHAR(50) NOT NULL, 16 | department_id INT NOT NULL, 17 | salary DOUBLE NOT NULL, 18 | CONSTRAINT `fk_department_id` FOREIGN KEY (`department_id`) REFERENCES `departments` (`id`) 19 | ); 20 | 21 | INSERT INTO `employees` (`first_name`,`last_name`, `job_title`,`department_id`,`salary`) VALUES 22 | ('John', 'Smith', 'Therapist',1, 900.00), 23 | ('John', 'Johnson', 'Acupuncturist',1, 880.00), 24 | ('Smith', 'Johnson', 'Technician',2, 1100.00), 25 | ('Peter', 'Petrov', 'Supervisor',3, 1100.00), 26 | ('Peter', 'Ivanov', 'Dentist',4, 1500.23), 27 | ('Ivan' ,'Petrov', 'Therapist',1, 990.00), 28 | ('Jack', 'Jackson', 'Epidemiologist',4, 1800.00), 29 | ('Pedro', 'Petrov', 'Medical Director',3, 2100.00), 30 | ('Nikolay', 'Ivanov', 'Nutrition Technician',4, 1600.00); 31 | 32 | 33 | 34 | CREATE TABLE rooms ( 35 | id INT PRIMARY KEY AUTO_INCREMENT, 36 | occupation VARCHAR(30) 37 | ); 38 | 39 | INSERT INTO rooms(`occupation`) VALUES('free'), ('occupied'),('free'),('free'),('occupied'); 40 | 41 | CREATE TABLE patients ( 42 | id INT PRIMARY KEY AUTO_INCREMENT, 43 | first_name VARCHAR(50), 44 | last_name VARCHAR(50), 45 | room_id INT NOT NULL 46 | ); 47 | 48 | INSERT INTO patients(`first_name`,`last_name`,`room_id`) VALUES('Pesho','Petrov',1),('Gosho','Georgiev',3),('Mariya','Marieva', 2), ('Katya','Katerinova', 2), ('Nikolay','Nikolaev',3); -------------------------------------------------------------------------------- /04. Built-in Functions/04. Built-in-Functions-Exercises.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/04. Built-in Functions/04. Built-in-Functions-Exercises.docx -------------------------------------------------------------------------------- /04. Built-in Functions/04. Built-in-Functions-Lab.docx.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/04. Built-in Functions/04. Built-in-Functions-Lab.docx.docx -------------------------------------------------------------------------------- /04. Built-in Functions/04. Built-in-Functions.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/04. Built-in Functions/04. Built-in-Functions.pdf -------------------------------------------------------------------------------- /04. Built-in Functions/Built-in Functions Exercises.sql: -------------------------------------------------------------------------------- 1 | -- Part I – Queries for SoftUni Database 2 | 3 | USE `soft_uni`; 4 | 5 | -- 01. Find Names of All Employees by First Name 6 | -- Write a SQL query to find first and last names of all employees whose 7 | -- first name starts with “Sa” (case insensitively). Order the information by id. 8 | 9 | SELECT 10 | `first_name`, `last_name` 11 | FROM 12 | `employees` 13 | WHERE 14 | `first_name` REGEXP '^Sa' 15 | ORDER BY `employee_id`; 16 | 17 | -- 02. Find Names of All Employees by Last Name 18 | -- Write a SQL query to find first and last names of all employees whose 19 | -- last name contains “ei” (case insensitively). Order the information by id. 20 | 21 | SELECT 22 | `first_name`, `last_name` 23 | FROM 24 | `employees` 25 | WHERE 26 | `last_name` LIKE '%ei%' 27 | ORDER BY `employee_id`; 28 | 29 | -- 03. Find First Names of All Employess 30 | -- Write a SQL query to find the first names of all employees in the departments 31 | -- with ID 3 or 10 and whose hire year is between 1995 and 2005 inclusive. 32 | -- Order the information by id. 33 | 34 | SELECT 35 | `first_name` 36 | FROM 37 | `employees` 38 | WHERE 39 | `department_id` IN (3, 10) 40 | AND YEAR(`hire_date`) >= 1995 41 | AND YEAR(`hire_date`) <= 2005 42 | ORDER BY `employee_id`; 43 | 44 | -- 04. Find All Employees Except Engineers 45 | -- Write a SQL query to find the first and last names of all employees 46 | -- whose job titles does not contain “engineer”. Order by id. 47 | 48 | SELECT 49 | `first_name`, `last_name` 50 | FROM 51 | `employees` 52 | WHERE 53 | `job_title` NOT LIKE '%engineer%' 54 | ORDER BY `employee_id`; 55 | 56 | -- 05. Find Towns with Name Length 57 | -- Write a SQL query to find town names that are 5 or 6 symbols long 58 | -- and order them alphabetically by town name. 59 | 60 | SELECT 61 | `name` 62 | FROM 63 | `towns` 64 | WHERE 65 | CHAR_LENGTH(`name`) BETWEEN 5 AND 6 66 | ORDER BY `name`; 67 | 68 | -- 06. Find Towns Starting With 69 | -- Write a SQL query to find all towns that start with letters 70 | -- M, K, B or E (case insensitively). Order them alphabetically by town name. 71 | 72 | SELECT 73 | * 74 | FROM 75 | `towns` 76 | WHERE 77 | `name` REGEXP '^[MmKkBbEe]' 78 | ORDER BY `name`; 79 | 80 | -- 07. Find Towns Not Starting With 81 | -- Write a SQL query to find all towns that does not start with letters 82 | -- R, B or D (case insensitively). Order them alphabetically by name. 83 | 84 | SELECT 85 | * 86 | FROM 87 | `towns` 88 | WHERE 89 | `name` REGEXP '^[^RrBbDd]' 90 | ORDER BY `name`; 91 | 92 | -- 08. Create View Employees Hired After 93 | -- Write a SQL query to create view v_employees_hired_after_2000 with 94 | -- first and last name to all employees hired after 2000 year. 95 | 96 | CREATE VIEW `v_employees_hired_after_2000` AS 97 | SELECT 98 | `first_name`, `last_name` 99 | FROM 100 | `employees` 101 | WHERE 102 | YEAR(`hire_date`) > 2000; 103 | 104 | -- 09. Length of Last Name 105 | -- Write a SQL query to find the names of all employees whose 106 | -- last name is exactly 5 characters long. 107 | 108 | SELECT 109 | `first_name`, `last_name` 110 | FROM 111 | `employees` 112 | WHERE 113 | CHAR_LENGTH(`last_name`) = 5; 114 | 115 | 116 | -- Part II – Queries for Geography Database 117 | 118 | USE `geography`; 119 | 120 | -- 10. Countries Holding 'A' 3 or More Times 121 | -- Find all countries that holds the letter 'A' in their name at least 3 times 122 | -- (case insensitively), sorted by ISO code. Display the country name and ISO code. 123 | 124 | SELECT 125 | `country_name`, `iso_code` 126 | FROM 127 | `countries` 128 | WHERE 129 | (CHAR_LENGTH(`country_name`) - CHAR_LENGTH(REPLACE(LOWER(`country_name`), 'a', ''))) >= 3 130 | ORDER BY `iso_code`; 131 | 132 | -- Alternative solution 133 | SELECT 134 | `country_name`, `iso_code` 135 | FROM 136 | `countries` 137 | WHERE 138 | `country_name` LIKE '%a%a%a%' 139 | ORDER BY `iso_code`; 140 | 141 | -- 11. Mix of Peak and River Names 142 | -- Combine all peak names with all river names, so that the last letter of each peak name 143 | -- is the same like the first letter of its corresponding river name. Display the peak 144 | -- names, river names, and the obtained mix. Sort the results by the obtained mix. 145 | 146 | SELECT 147 | `peak_name`, 148 | `river_name`, 149 | LOWER(CONCAT(`peak_name`, SUBSTRING(`river_name`, 2))) AS 'mix' 150 | FROM 151 | `peaks`, 152 | `rivers` 153 | WHERE 154 | LOWER(RIGHT(`peak_name`, 1)) = LOWER(LEFT(`river_name`, 1)) 155 | ORDER BY `mix`; 156 | 157 | 158 | -- Part III – Queries for Diablo Database 159 | 160 | USE `diablo`; 161 | 162 | -- 12. Games From 2011 and 2012 Year 163 | -- Find the top 50 games ordered by start date, then by name of the game. Display only 164 | -- games from 2011 and 2012 year. Display start date in the format “YYYY-MM-DD”. 165 | 166 | SELECT 167 | `name`, DATE_FORMAT(`start`, '%Y-%m-%d') AS 'start' 168 | FROM 169 | `games` 170 | WHERE 171 | YEAR(`start`) BETWEEN 2011 AND 2012 172 | ORDER BY `start` , `name` 173 | LIMIT 50; 174 | 175 | -- 13. User Email Providers 176 | -- Find all users along with information about their email providers. Display the 177 | -- user_name and email provider. Sort the results by email provider alphabetically, 178 | -- then by username. 179 | 180 | SELECT 181 | `user_name`, 182 | SUBSTRING_INDEX(`email`, '@', - 1) AS 'Email Provider' 183 | FROM 184 | `users` 185 | ORDER BY `Email Provider` , `user_name`; 186 | 187 | -- 14. Get Users with IP Address Like Pattern 188 | -- Find all user_name and ip_address for each user sorted by user_name alphabetically. 189 | -- Display only rows that ip_address matches the pattern: “___.1%.%.___”. 190 | 191 | SELECT 192 | `user_name`, `ip_address` 193 | FROM 194 | `users` 195 | WHERE 196 | `ip_address` LIKE '___.1%.%.___' 197 | ORDER BY `user_name`; 198 | 199 | -- 15. Show All Games with Duration and Part of the Day 200 | -- Find all games with part of the day and duration. Parts of the day should be 201 | -- Morning (start time is >= 0 and < 12), Afternoon (start time is >= 12 and < 18), 202 | -- Evening (start time is >= 18 and < 24). Duration should be Extra Short 203 | -- (smaller or equal to 3), Short (between 3 and 6 including), Long (between 6 and 10 including) 204 | -- and Extra Long in any other cases or without duration. 205 | 206 | SELECT 207 | `name` AS 'game', 208 | CASE 209 | WHEN HOUR(`start`) BETWEEN 0 AND 11 THEN 'Morning' 210 | WHEN HOUR(`start`) BETWEEN 12 AND 17 THEN 'Afternoon' 211 | ELSE 'Evening' 212 | END AS 'Part of the Day', 213 | CASE 214 | WHEN `duration` <= 3 THEN 'Extra Short' 215 | WHEN `duration` BETWEEN 4 AND 6 THEN 'Short' 216 | WHEN `duration` BETWEEN 7 AND 10 THEN 'Long' 217 | ELSE 'Extra Long' 218 | END AS 'Duration' 219 | FROM 220 | `games` 221 | ORDER BY `name`; 222 | 223 | -- Another solution 224 | SELECT 225 | `name` AS 'game', 226 | CASE 227 | WHEN HOUR(`start`) < 12 THEN 'Morning' 228 | WHEN HOUR(`start`) < 18 THEN 'Afternoon' 229 | ELSE 'Evening' 230 | END AS 'Part of the Day', 231 | CASE 232 | WHEN `duration` < 4 THEN 'Extra Short' 233 | WHEN `duration` < 7 THEN 'Short' 234 | WHEN `duration` < 11 THEN 'Long' 235 | ELSE 'Extra Long' 236 | END AS 'Duration' 237 | FROM 238 | `games` 239 | ORDER BY `name`; 240 | 241 | -- Part IV – Date Functions Queries 242 | 243 | USE `orders`; 244 | 245 | -- 16. Orders Table 246 | -- You are given a table orders(id, product_name, order_date) filled with data. 247 | -- Consider that the payment for that order must be accomplished within 3 days 248 | -- after the order date. Also the delivery date is up to 1 month. Write a query 249 | -- to show each product’s name, order date, pay and deliver due dates. 250 | 251 | SELECT 252 | `product_name`, 253 | `order_date`, 254 | DATE_ADD(`order_date`, INTERVAL 3 DAY) AS 'pay_due', 255 | DATE_ADD(`order_date`, INTERVAL 1 MONTH) AS 'deliver_due' 256 | FROM 257 | `orders`; -------------------------------------------------------------------------------- /04. Built-in Functions/Built-in Functions Lab.sql: -------------------------------------------------------------------------------- 1 | -- Download from the course instance and get familiar with the book_library database. 2 | -- You will use it in the following exercises. 3 | 4 | USE `book_library`; 5 | 6 | -- 01. Find Book Titles 7 | -- Write a SQL query to find books which titles start with “The”. 8 | -- Order the result by id. 9 | 10 | SELECT 11 | `title` 12 | FROM 13 | `books` 14 | WHERE 15 | SUBSTRING(`title`, 1, 3) = 'The' 16 | ORDER BY `id`; 17 | 18 | -- 02. Replace Titles 19 | -- Write a SQL query to find books which titles start with “The” and 20 | -- replace the substring with 3 asterisks. Retrieve data about the 21 | -- updated titles. Order the result by id. 22 | 23 | -- Concat + Substring solution 24 | SELECT 25 | CONCAT('***', SUBSTRING(`title`, 4)) AS 'title' 26 | FROM 27 | `books` 28 | WHERE 29 | SUBSTRING(`title`, 1, 3) = 'The' 30 | ORDER BY `id`; 31 | 32 | -- Replace solution 33 | SELECT 34 | REPLACE(`title`, 'The', '***') AS 'title' 35 | FROM 36 | `books` 37 | WHERE 38 | `title` LIKE ('The%') 39 | ORDER BY `id`; 40 | 41 | -- 03. Sum Cost of All Books 42 | -- Write a SQL query to sum prices of all books. 43 | -- Format the output to 2 digits after decimal point. 44 | 45 | SELECT 46 | ROUND(SUM(`cost`), 2) AS 'cost' 47 | FROM 48 | `books`; 49 | 50 | -- 04. Days Lived 51 | -- Write a SQL query to calculate the days that the authors have lived. 52 | -- NULL values mean that the author is still alive. 53 | 54 | SELECT 55 | CONCAT_WS(' ', `first_name`, `last_name`) AS 'Full Name', 56 | TIMESTAMPDIFF(DAY, `born`, `died`) AS 'Days Lived' 57 | FROM 58 | `authors`; 59 | 60 | -- 05. Harry Potter Books 61 | -- Write a SQL query to retrieve titles of all the Harry Potter books. 62 | -- Order the information by id. 63 | 64 | SELECT 65 | `title` 66 | FROM 67 | `books` 68 | WHERE 69 | `title` LIKE ('%Harry Potter%') 70 | ORDER BY `id`; -------------------------------------------------------------------------------- /04. Built-in Functions/Databases/DemoBD20170125.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/04. Built-in Functions/Databases/DemoBD20170125.sql -------------------------------------------------------------------------------- /04. Built-in Functions/Databases/Orders-Database.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE orders; 2 | 3 | USE orders; 4 | 5 | CREATE TABLE orders 6 | ( 7 | id INT NOT NULL, 8 | product_name VARCHAR(50) NOT NULL, 9 | order_date DATETIME NOT NULL, 10 | CONSTRAINT pk_orders PRIMARY KEY (id) 11 | ); 12 | 13 | INSERT INTO orders (id, product_name, order_date) VALUES (1, 'Butter', '20160919'); 14 | INSERT INTO orders (id, product_name, order_date) VALUES (2, 'Milk', '20160930'); 15 | INSERT INTO orders (id, product_name, order_date) VALUES (3, 'Cheese', '20160904'); 16 | INSERT INTO orders (id, product_name, order_date) VALUES (4, 'Bread', '20151220'); 17 | INSERT INTO orders (id, product_name, order_date) VALUES (5, 'Tomatoes', '20150101'); 18 | INSERT INTO orders (id, product_name, order_date) VALUES (6, 'Tomatoe2', '20150201'); 19 | INSERT INTO orders (id, product_name, order_date) VALUES (7, 'Tomatoess', '20150401'); 20 | INSERT INTO orders (id, product_name, order_date) VALUES (8, 'Tomatoe3', '20150128'); 21 | INSERT INTO orders (id, product_name, order_date) VALUES (9, 'Tomatoe4', '20150628'); 22 | INSERT INTO orders (id, product_name, order_date) VALUES (10, 'Tomatoe44s', '20150630'); 23 | INSERT INTO orders (id, product_name, order_date) VALUES (11, 'Tomatoefggs', '20150228'); 24 | INSERT INTO orders (id, product_name, order_date) VALUES (12, 'Tomatoesytu', '20160228'); 25 | INSERT INTO orders (id, product_name, order_date) VALUES (13, 'Toyymatddoehys', '20151231'); 26 | INSERT INTO orders (id, product_name, order_date) VALUES (14, 'Tom443atoes', '20151215'); 27 | INSERT INTO orders (id, product_name, order_date) VALUES (15, 'Tomat65434foe23gfhgsPep', '20151004'); -------------------------------------------------------------------------------- /04. Built-in Functions/Databases/booklibrary.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE book_library; 2 | USE book_library; 3 | 4 | CREATE TABLE authors ( 5 | id INT PRIMARY KEY AUTO_INCREMENT, 6 | first_name VARCHAR(30) NOT NULL, 7 | middle_name VARCHAR(30), 8 | last_name VARCHAR(30) NOT NULL, 9 | born DATETIME NOT NULL, 10 | died DATETIME 11 | ); 12 | 13 | INSERT INTO authors(id,first_name, middle_name, last_name, born, died) VALUES 14 | (1,'Agatha', 'Mary Clarissa','Christie', '1890-09-15', '1976-01-12'), 15 | (2,'William', NULL,'Shakespeare', '1564-04-26', '1616-04-23'), 16 | (3,'Danielle', 'Fernandes Dominique', 'Schuelein-Steel', '1947-07-14', NULL), 17 | (4,'Joanne', NULL,'Rowling' , '1965-07-31', NULL), 18 | (5,'Lev', 'Nikolayevich', 'Tolstoy', '1828-09-09', '1910-11-20'), 19 | (6,'Paulo', 'Coelho de', 'Souza', '1947-08-24', NULL), 20 | (7,'Stephen', 'Edwin', 'King', '1947-09-21', NULL), 21 | (8,'John', 'Ronald Reuel', 'Tolkien', '1892-01-03', '1973-09-02'), 22 | (9,'Erika', NULL, 'Mitchell', '1963-03-07', NULL); 23 | 24 | CREATE TABLE books ( 25 | id INT PRIMARY KEY AUTO_INCREMENT, 26 | title VARCHAR(100) NOT NULL, 27 | author_id INT NOT NULL, 28 | year_of_release datetime, 29 | cost DOUBLE NOT NULL, 30 | CONSTRAINT fk_author_id FOREIGN KEY (author_id) REFERENCES authors(id) 31 | ); 32 | 33 | INSERT INTO books(author_id,title, year_of_release,cost) VALUES 34 | (1,'Unfinished Portrait', '1930-00-00', 15.99), 35 | (1,'The Mysterious Affair at Styles', '1920-00-00',17.99), 36 | (1,'The Big Four', '1927-00-00',14.99), 37 | (1,'The Murder at the Vicarage', '1930-00-00',13.99), 38 | (1,'The Mystery of the Blue Train', '1928-00-00',12.99), 39 | (2,'Julius Caesar', '1599-00-00',11.99), 40 | (2,'Timon of Athens', '1607-00-00',13.99), 41 | (2,'As You Like It', '1600-00-00',18.99), 42 | (2,'A Midsummer Night\'s Dream', '1595-00-00',15.99), 43 | (3,'Going Home', '1973-00-00',15.99), 44 | (3,'The Ring', '1980-00-00',14.99), 45 | (3,'Secrets', '1985-00-00',15.99), 46 | (3,'Message From Nam', '1990-00-00',13.99), 47 | (4,'Career of Evil', '2015-00-00',15.99), 48 | (4, 'Harry Potter and the Philosopher\'s Stone','1997-00-00',19.99), 49 | (4,'Harry Potter and the Chamber of Secrets','1998-00-00',19.99), 50 | (4,'Harry Potter and the Prisoner of Azkaban','1999-00-00',19.99), 51 | (4,'Harry Potter and the Goblet of Fire','2000-00-00',19.99), 52 | (4,'Harry Potter and the Order of the Phoenix','2003-00-00',19.99), 53 | (4,'Harry Potter and the Half-Blood Prince','2005-00-00',19.99), 54 | (4,'Harry Potter and the Deathly Hallows','2007-00-00',19.99), 55 | (4,'Harry Potter and the Deathly Hallows','2007-00-00',15.99), 56 | (5,'Anna Karenina','1877-00-00',15.99), 57 | (5,'War And Peace','1869-00-00',30), 58 | (5,'Boyhood','1854-00-00',15.99), 59 | (6,'By the River Piedra I Sat Down and Wept','1994-00-00',15.99), 60 | (6,'The Alchemist','1988-00-00',15.99), 61 | (6,'The Fifth Mountain','1996-00-00',15.99), 62 | (6,'The Zahir','2005-00-00',15.99), 63 | (7,'Rage','1977-00-00',13.99), 64 | (7,'The Dead Zone','1979-00-00',13.99), 65 | (7,'It','1986-00-00',13.99), 66 | (7,'It','1986-00-00',13.99), 67 | (8,'The Hobbit','1937-00-00',20.99), 68 | (8,'The Adventures of Tom Bombadil','1962-00-00',13.99), 69 | (9,'Fifty Shades of Grey','2011-00-00',13.99), 70 | (9,'Fifty Shades Darker','2012-00-00',13.99), 71 | (9,'Fifty Shades Freed','2012-00-00',13.99); -------------------------------------------------------------------------------- /05. Data Aggregation/05. Data-Aggregation-Exercises.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/05. Data Aggregation/05. Data-Aggregation-Exercises.docx -------------------------------------------------------------------------------- /05. Data Aggregation/05. Data-Aggregation-Lab.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/05. Data Aggregation/05. Data-Aggregation-Lab.docx -------------------------------------------------------------------------------- /05. Data Aggregation/05. Data-Aggregation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/05. Data Aggregation/05. Data-Aggregation.pdf -------------------------------------------------------------------------------- /05. Data Aggregation/Data Aggregation Exercises.sql: -------------------------------------------------------------------------------- 1 | -- https://judge.softuni.bg/Contests/Compete/Index/296#0 2 | 3 | -- Get familiar with the gringotts database. You will use it in the assignments below. 4 | 5 | USE `gringotts`; 6 | 7 | -- 01. Records’ Count 8 | -- Import the database and send the total count of records to Mr. Bodrog. 9 | -- Make sure nothing got lost. 10 | 11 | SELECT 12 | COUNT(`id`) AS 'count' 13 | FROM 14 | `wizzard_deposits`; 15 | 16 | 17 | -- 02. Longest Magic Wand 18 | -- Select the size of the longest magic wand. Rename the new column appropriately. 19 | 20 | SELECT 21 | MAX(`magic_wand_size`) AS 'longest_magic_wand' 22 | FROM 23 | `wizzard_deposits`; 24 | 25 | 26 | -- 03. Longest Magic Wand per Deposit Groups 27 | -- For wizards in each deposit group show the longest magic wand. Sort result by 28 | -- longest magic wand for each deposit group in increasing order, then by 29 | -- deposit_group alphabetically. Rename the new column appropriately. 30 | 31 | SELECT 32 | `deposit_group`, 33 | MAX(`magic_wand_size`) AS 'longest_magic_wand' 34 | FROM 35 | `wizzard_deposits` 36 | GROUP BY `deposit_group` 37 | ORDER BY `longest_magic_wand` , `deposit_group`; 38 | 39 | 40 | -- 04. Smallest Deposit Group per Magic Wand Size 41 | -- Select the deposit group with the lowest average wand size. 42 | 43 | SELECT 44 | `deposit_group` 45 | FROM 46 | `wizzard_deposits` 47 | GROUP BY `deposit_group` 48 | ORDER BY AVG(`magic_wand_size`) 49 | LIMIT 1; 50 | 51 | 52 | -- 05. Deposits Sum 53 | -- Select all deposit groups and its total deposit sum. 54 | -- Sort result by total_sum in increasing order. 55 | 56 | SELECT 57 | `deposit_group`, 58 | SUM(`deposit_amount`) AS 'total_sum' 59 | FROM 60 | `wizzard_deposits` 61 | GROUP BY `deposit_group` 62 | ORDER BY `total_sum`; 63 | 64 | 65 | -- 06. Deposits Sum for Ollivander Family 66 | -- Select all deposit groups and its total deposit sum but only for 67 | -- the wizards who has their magic wand crafted by Ollivander family. 68 | -- Sort result by deposit_group alphabetically. 69 | 70 | SELECT 71 | `deposit_group`, 72 | SUM(`deposit_amount`) AS 'total_sum' 73 | FROM 74 | `wizzard_deposits` 75 | WHERE 76 | `magic_wand_creator` = 'Ollivander family' 77 | GROUP BY `deposit_group` 78 | ORDER BY `deposit_group`; 79 | 80 | 81 | -- 07. Deposits Filter 82 | -- Select all deposit groups and its total deposit sum but only for 83 | -- the wizards who has their magic wand crafted by Ollivander family. 84 | -- After this, filter total deposit sums lower than 150000. 85 | -- Order by total deposit sum in descending order. 86 | 87 | SELECT 88 | `deposit_group`, 89 | SUM(`deposit_amount`) AS 'total_sum' 90 | FROM 91 | `wizzard_deposits` 92 | WHERE 93 | `magic_wand_creator` = 'Ollivander family' 94 | GROUP BY `deposit_group` 95 | HAVING `total_sum` < 150000 96 | ORDER BY `total_sum` DESC; 97 | 98 | -- 08. Deposit Charge 99 | -- Create a query that selects: 100 | -- • Deposit group 101 | -- • Magic wand creator 102 | -- • Minimum deposit charge for each group 103 | -- Group by deposit_group and magic_wand_creator. 104 | -- Select the data in ascending order by magic_wand_creator and deposit_group. 105 | 106 | SELECT 107 | `deposit_group`, 108 | `magic_wand_creator`, 109 | MIN(`deposit_charge`) AS 'min_deposit_charge' 110 | FROM 111 | `wizzard_deposits` 112 | GROUP BY `deposit_group` , `magic_wand_creator` 113 | ORDER BY `magic_wand_creator` , `deposit_group`; 114 | 115 | 116 | -- 09. Age Groups 117 | -- Write down a query that creates 7 different groups based on their age. 118 | -- Age groups should be as follows: 119 | -- • [0-10] 120 | -- • [11-20] 121 | -- • [21-30] 122 | -- • [31-40] 123 | -- • [41-50] 124 | -- • [51-60] 125 | -- • [61+] 126 | -- The query should return: 127 | -- • Age groups 128 | -- • Count of wizards in it 129 | -- Sort result by increasing size of age groups. 130 | 131 | SELECT 132 | CASE 133 | WHEN age <= 10 THEN '[0-10]' 134 | WHEN age <= 20 THEN '[11-20]' 135 | WHEN age <= 30 THEN '[21-30]' 136 | WHEN age <= 40 THEN '[31-40]' 137 | WHEN age <= 50 THEN '[41-50]' 138 | WHEN age <= 60 THEN '[51-60]' 139 | ELSE '[61+]' 140 | END AS 'age_group', 141 | COUNT(*) AS 'wizard_count' 142 | FROM 143 | `wizzard_deposits` 144 | GROUP BY `age_group` 145 | ORDER BY `wizard_count`; 146 | 147 | 148 | -- 10. First Letter 149 | -- Write a query that returns all unique wizard first letters of their 150 | -- first names only if they have deposit of type Troll Chest. 151 | -- Order them alphabetically. Use GROUP BY for uniqueness. 152 | 153 | SELECT 154 | LEFT(`first_name`, 1) AS 'first_letter' 155 | FROM 156 | `wizzard_deposits` 157 | WHERE 158 | `deposit_group` = 'Troll Chest' 159 | GROUP BY `first_letter` 160 | ORDER BY `first_letter`; 161 | 162 | 163 | -- 11. Average Interest 164 | -- Mr. Bodrog is highly interested in profitability. He wants to know the 165 | -- average interest of all deposits groups split by whether the deposit 166 | -- has expired or not. But that’s not all. He wants you to select deposits 167 | -- with start date after 01/01/1985. Order the data descending by 168 | -- Deposit Group and ascending by Expiration Flag. 169 | 170 | SELECT 171 | `deposit_group`, 172 | `is_deposit_expired`, 173 | AVG(`deposit_interest`) AS `deposit_interest` 174 | FROM 175 | `wizzard_deposits` 176 | WHERE 177 | `deposit_start_date` > '1985-01-01' 178 | GROUP BY `deposit_group` , `is_deposit_expired` 179 | ORDER BY `deposit_group` DESC , `is_deposit_expired`; 180 | 181 | 182 | -- 12. Rich Wizard, Poor Wizard * 183 | -- Give Mr. Bodrog some data to play his favorite game Rich Wizard, Poor Wizard. 184 | -- The rules are simple: You compare the deposits of every wizard with the wizard 185 | -- after him. If a wizard is the last one in the database, simply ignore it. 186 | -- At the end you have to sum the difference between the deposits: 187 | -- 188 | -- host_wizard host_wizard_deposit guest_wizard guest_wizard_deposit difference 189 | -- Harry 10 000 Tom 12 000 -2000 190 | -- Tom 12 000 … … … 191 | -- 192 | -- At the end your query should return a single value: the SUM of all differences: 193 | -- 194 | -- sum_difference 195 | -- 44393.97 196 | 197 | SELECT 198 | SUM(`hw`.`deposit_amount` - `gw`.`deposit_amount`) AS 'sum_difference' 199 | FROM 200 | `wizzard_deposits` AS `hw`, 201 | `wizzard_deposits` AS `gw` 202 | WHERE 203 | `gw`.`id` - `hw`.`id` = 1; 204 | 205 | -- Show details 206 | SELECT 207 | `hw`.`first_name` AS 'host_wizard', 208 | `hw`.`deposit_amount` AS 'host_wizard_deposit', 209 | `gw`.`first_name` AS 'guest_wizard', 210 | `gw`.`deposit_amount` AS 'guest_wizard_deposit', 211 | (`hw`.`deposit_amount` - `gw`.`deposit_amount`) AS 'difference' 212 | FROM 213 | `wizzard_deposits` AS `hw`, `wizzard_deposits` AS `gw` 214 | WHERE 215 | `gw`.`id` - `hw`.`id` = 1; 216 | 217 | 218 | 219 | -- That’s it! You no longer work for Mr. Bodrog. 220 | -- You have decided to find a proper job as an analyst in SoftUni. 221 | -- It’s not a surprise that you will use the soft_uni database. 222 | 223 | USE `soft_uni`; 224 | 225 | 226 | -- 13. Employees Minimum Salaries 227 | -- Select the minimum salary from the employees for departments with 228 | -- ID (2,5,7) but only for those who are hired after 01/01/2000. 229 | -- Sort result by department_id in ascending order. 230 | -- Your query should return: 231 | -- • department_id 232 | -- • minimum_salary 233 | 234 | SELECT 235 | `department_id`, MIN(`salary`) AS 'minimum_salary' 236 | FROM 237 | `employees` 238 | WHERE 239 | `department_id` IN (2 , 5, 7) 240 | GROUP BY `department_id` 241 | ORDER BY `department_id`; 242 | 243 | 244 | -- 14. Employees Average Salaries 245 | -- Select all high paid employees who earn more than 30000 into a new table. 246 | -- Then delete all high paid employees who have manager_id = 42 from the new table; 247 | -- Then increase the salaries of all high paid employees with department_id =1 248 | -- with 5000 in the new table. Finally, select the average salaries in each 249 | -- department from the new table. Sort result by department_id in increasing order. 250 | 251 | SELECT 252 | `department_id`, 253 | CASE 254 | WHEN `department_id` = 1 THEN AVG(`salary`) + 5000 255 | ELSE AVG(`salary`) 256 | END AS 'avg_salary' 257 | FROM 258 | `employees` 259 | WHERE 260 | `salary` > 30000 AND `manager_id` != 42 261 | GROUP BY `department_id` 262 | ORDER BY `department_id`; 263 | 264 | 265 | -- 15. Employees Maximum Salaries 266 | -- Find the max salary for each department. Filter those which have max salaries not 267 | -- in the range 30000 and 70000. Sort result by department_id in increasing order. 268 | 269 | SELECT 270 | `department_id`, MAX(`salary`) AS 'max_salary' 271 | FROM 272 | `employees` 273 | GROUP BY `department_id` 274 | HAVING NOT `max_salary` BETWEEN 30000 AND 70000 275 | ORDER BY `department_id`; 276 | 277 | 278 | -- 16. Employees Count Salaries 279 | -- Count the salaries of all employees who don’t have a manager. 280 | 281 | SELECT 282 | COUNT(`salary`) 283 | FROM 284 | `employees` 285 | WHERE 286 | ISNULL(`manager_id`); 287 | 288 | 289 | -- 17. 3rd Highest Salary 290 | -- Find the third highest salary in each department if there is such. 291 | -- Sort result by department_id in increasing order. 292 | 293 | SELECT 294 | `emp`.`department_id`, 295 | MAX(`emp`.`salary`) AS 'third_highest_salary' 296 | FROM 297 | `employees` AS `emp` 298 | JOIN 299 | (SELECT 300 | `e`.`department_id`, MAX(`e`.`salary`) AS `max_salary` 301 | FROM 302 | `employees` AS `e` 303 | JOIN (SELECT 304 | `e`.`department_id`, MAX(`e`.`salary`) AS `max_salary` 305 | FROM 306 | `employees` AS `e` 307 | GROUP BY `e`.`department_id`) AS `first_max_salary` ON `e`.`department_id` = `first_max_salary`.`department_id` 308 | WHERE 309 | `e`.`salary` < `first_max_salary`.`max_salary` 310 | GROUP BY `e`.`department_id`) AS `second_max_salary` ON `emp`.`department_id` = `second_max_salary`.`department_id` 311 | WHERE 312 | `emp`.`salary` < `second_max_salary`.`max_salary` 313 | GROUP BY `emp`.`department_id` 314 | ORDER BY `emp`.`department_id`; 315 | 316 | -- Solution with variables, crashes in Judge :( 317 | SET @num := 0, @type := ''; 318 | SELECT 319 | `department_id`, `salary` AS 'third_highest_salary' 320 | FROM 321 | (SELECT 322 | `department_id`, 323 | `salary`, 324 | @num:=IF(@type = `department_id`, @num + 1, 1) AS `row_number`, 325 | @type:=`department_id` 326 | FROM 327 | (SELECT 328 | `department_id`, `salary` 329 | FROM 330 | `employees` 331 | GROUP BY `department_id` , `salary` 332 | ORDER BY `department_id` , `salary` DESC) AS `a`) AS `b` 333 | WHERE 334 | `row_number` = 3 335 | ORDER BY `department_id`; 336 | 337 | -- An inteligent solution: 338 | -- https://softuni.bg/forum/14032/problem-18-3rd-highest-salary-judge#comment-60937 339 | SELECT 340 | `department_id`, 341 | (SELECT DISTINCT 342 | `e2`.`salary` 343 | FROM 344 | `employees` AS `e2` 345 | WHERE 346 | `e2`.`department_id` = `e1`.`department_id` 347 | ORDER BY `e2`.`salary` DESC 348 | LIMIT 2 , 1) AS `third_highest_salary` 349 | FROM 350 | `employees` AS `e1` 351 | GROUP BY `department_id` 352 | HAVING `third_highest_salary` IS NOT NULL; 353 | 354 | -- 18. Salary Challenge 355 | -- Write a query that returns: 356 | -- • first_name 357 | -- • last_name 358 | -- • department_id 359 | -- for all employees who have salary higher than the average salary of their 360 | -- respective departments. Select only the first 10 rows. Order by department_id. 361 | 362 | SELECT 363 | `e`.`first_name`, `e`.`last_name`, `e`.`department_id` 364 | FROM 365 | `employees` AS `e` 366 | JOIN 367 | (SELECT 368 | `department_id`, AVG(`salary`) AS 'dep_avg_salary' 369 | FROM 370 | `employees` 371 | GROUP BY `department_id`) AS `avrg` ON `e`.`department_id` = `avrg`.`department_id` 372 | WHERE 373 | `salary` > `avrg`.`dep_avg_salary` 374 | ORDER BY `department_id` 375 | LIMIT 10; 376 | 377 | 378 | -- 19. Departments Total Salaries 379 | -- Create a query which shows the total sum of salaries for each department. Order by department_id. 380 | -- Your query should return: 381 | -- • department_id 382 | -- • total_salary 383 | 384 | SELECT 385 | `department_id`, SUM(`salary`) AS 'total_salary' 386 | FROM 387 | `employees` 388 | GROUP BY `department_id` 389 | ORDER BY `department_id`; -------------------------------------------------------------------------------- /05. Data Aggregation/Data Aggregation Lab.sql: -------------------------------------------------------------------------------- 1 | -- https://judge.softuni.bg/Contests/Practice/Index/744#0 2 | 3 | USE `restaurant`; 4 | 5 | -- 1. Departments Info 6 | -- Write a query to count the number of employees in each department by id. 7 | -- Order the information by deparment_id, then by employees count. 8 | 9 | SELECT 10 | `department_id`, COUNT(`id`) AS 'Number of employees' 11 | FROM 12 | `employees` 13 | GROUP BY `department_id` 14 | ORDER BY `department_id`, COUNT(`id`); 15 | 16 | 17 | -- 2. Average Salary 18 | -- Write a query to calculate the average salary in each department. 19 | -- Order the information by department_id. Round the salary result 20 | -- to two digits after the decimal point. 21 | 22 | SELECT 23 | `department_id`, ROUND(AVG(`salary`), 2) AS 'Average Salary' 24 | FROM 25 | `employees` 26 | GROUP BY `department_id` 27 | ORDER BY `department_id`; 28 | 29 | -- 3. Minimum Salary 30 | -- Write a query to retrieve information about the departments 31 | -- grouped by department_id with minumum salary higher than 800. 32 | -- Round the salary result to two digits after the decimal point. 33 | 34 | SELECT 35 | `department_id`, ROUND(MIN(`salary`), 2) AS 'Min Salary' 36 | FROM 37 | `employees` 38 | WHERE 39 | `salary` > 800 40 | GROUP BY `department_id` 41 | ORDER BY `department_id` 42 | LIMIT 1; 43 | 44 | -- Solution with use of HAVING 45 | SELECT 46 | `department_id`, ROUND(MIN(`salary`), 2) AS 'Min Salary' 47 | FROM 48 | `employees` 49 | GROUP BY `department_id` 50 | HAVING `Min Salary` > 800 51 | ORDER BY `department_id`; 52 | 53 | -- 4. Appetizers Count 54 | -- Write a query to retrieve the count of all appetizers (category id = 2) 55 | -- with price higher than 8. 56 | 57 | SELECT 58 | COUNT(`id`) AS 'Appetizers' 59 | FROM 60 | `products` 61 | WHERE 62 | `category_id` = 2 AND `price` > 8 63 | GROUP BY `category_id`; 64 | 65 | -- 5. Menu Prices 66 | -- Write a query to retrieve information about the prices of each category. 67 | -- The output should consist of: 68 | -- * category_id 69 | -- * Average Price 70 | -- * Cheapest Product 71 | -- * Most Expensive Product 72 | -- See the examples for more information. 73 | -- Round the results to 2 digits after the decimal point. 74 | 75 | SELECT 76 | `category_id`, 77 | ROUND(AVG(`price`), 2) AS 'Average Price', 78 | ROUND(MIN(`price`), 2) AS 'Cheapest Product', 79 | ROUND(MAX(`price`), 2) AS 'Most Expensive Product' 80 | FROM 81 | `products` 82 | GROUP BY `category_id` 83 | ORDER BY `category_id`; 84 | 85 | 86 | -- Tasks from presentation slides 87 | 88 | -- Write a query which prints the total sum of salaries for each 89 | -- department in the soft_uni database 90 | -- Order them by DepartmentID (ascending) 91 | 92 | USE `soft_uni`; 93 | SELECT 94 | `department_id`, ROUND(SUM(`salary`), 2) AS 'total_salary' 95 | FROM 96 | `employees` 97 | GROUP BY `department_id` 98 | ORDER BY `department_id`; -------------------------------------------------------------------------------- /05. Data Aggregation/Databases/restaurant.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE IF NOT EXISTS restaurant; 2 | use restaurant; 3 | 4 | CREATE TABLE departments ( 5 | id INT PRIMARY KEY AUTO_INCREMENT, 6 | name VARCHAR(100) NOT NULL 7 | ); 8 | 9 | CREATE TABLE employees ( 10 | id INT PRIMARY KEY AUTO_INCREMENT, 11 | first_name VARCHAR(30) NOT NULL, 12 | last_name VARCHAR(30) NOT NULL, 13 | department_id INT NOT NULL, 14 | salary DOUBLE NOT NULL, 15 | CONSTRAINT fk_department_id FOREIGN KEY(`department_id`) REFERENCES departments(`id`) 16 | ); 17 | 18 | CREATE TABLE categories ( 19 | id INT PRIMARY KEY AUTO_INCREMENT, 20 | name VARCHAR(30) NOT NULL 21 | ); 22 | 23 | CREATE TABLE products ( 24 | id INT PRIMARY KEY AUTO_INCREMENT, 25 | name VARCHAR(50) NOT NULL, 26 | category_id INT NOT NULL, 27 | price DOUBLE NOT NULL, 28 | CONSTRAINT fk_cateogory_id FOREIGN KEY(`category_id`) REFERENCES categories(`id`) 29 | ); 30 | 31 | INSERT INTO departments(name) VALUES ("Management"), ("Kitchen Staff"), ("Wait Staff"); 32 | 33 | INSERT INTO employees (first_name, last_name, department_id, salary) VALUES ("Jasmine","Maggot",2,1250.00), 34 | ("Nancy","Olson",2,1350.00), ("Karen","Bender",1,2400.00), ("Pricilia","Parker",2,980.00), 35 | ("Stephen","Bedford",2,780.00),("Jack","McGee",1,1700.00),("Clarence","Willis",3,650.00), 36 | ("Michael","Boren",3,780.00),("Michael","Boren",3,780.00); 37 | 38 | INSERT INTO categories(name) VALUES("salads"),("appetizers"),("soups"),("main"),("desserts"); 39 | 40 | INSERT INTO products (name, category_id,price) VALUES ("Lasagne", 4,12.99), 41 | ("Linguine Positano with Chicken", 4,11.69), 42 | ("Chicken Marsala", 4,13.69), 43 | ("Calamari", 2,14.89), 44 | ("Tomato Caprese with Fresh Burrata", 2,7.99), 45 | ("Wood-Fired Italian Wings", 2,9.90), 46 | ("Caesar Side Salad", 1,8.79), 47 | ("House Side Salad", 1,6.79), 48 | ("Johny Rocco Salad", 1,6.90), 49 | ("Minestrone", 3,8.89), 50 | ("Sausage & Lentil", 3,7.90), 51 | ("Mama Mandola’s Sicilian Chicken Soup", 3,6.90), 52 | ("Tiramisú", 5,4.90), 53 | ("John Cole", 5,5.60), 54 | ("Mini Cannoli", 5,5.60); -------------------------------------------------------------------------------- /06. Table Relations/06. Table-Relations-Exercises.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/06. Table Relations/06. Table-Relations-Exercises.docx -------------------------------------------------------------------------------- /06. Table Relations/06. Table-Relations-Lab.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/06. Table Relations/06. Table-Relations-Lab.docx -------------------------------------------------------------------------------- /06. Table Relations/06. Table-Relations.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/06. Table Relations/06. Table-Relations.pdf -------------------------------------------------------------------------------- /06. Table Relations/Databases/camp.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE camp; 2 | use camp; 3 | 4 | CREATE TABLE rooms( 5 | id INT PRIMARY KEY, 6 | occupation VARCHAR(20) not null, 7 | beds_count int not null 8 | ); 9 | 10 | CREATE TABLE vehicles( 11 | id int primary key auto_increment not null, 12 | driver_id int not null, 13 | vehicle_type varchar(30) not null, 14 | passengers int not null 15 | ); 16 | 17 | CREATE TABLE campers( 18 | id INT PRIMARY KEY auto_increment, 19 | first_name varchar(20) not null, 20 | last_name varchar(20) not null, 21 | age int not null, 22 | room int, 23 | vehicle_id int, 24 | CONSTRAINT fk_room_id FOREIGN KEY(room) REFERENCES rooms(id), 25 | CONSTRAINT fk_vehicle_id FOREIGN KEY(vehicle_id) REFERENCES vehicles(id) on delete cascade 26 | ); 27 | 28 | CREATE TABLE routes( 29 | id INT PRIMARY KEY auto_increment, 30 | starting_point varchar(30) not null, 31 | end_point varchar(30) not null, 32 | leader_id int not null, 33 | route_time TIME NOT NULL, 34 | CONSTRAINT fk_leader_id FOREIGN KEY(leader_id) REFERENCES campers(id) 35 | ); 36 | 37 | insert into rooms(id,occupation,beds_count) values(101,"occupied",3), 38 | (102,"free",3), 39 | (103,"free",3), 40 | (104,"free",2), 41 | (105,"free",2), 42 | (201,"free",3), 43 | (202,"free",3), 44 | (203,"free",2), 45 | (204,"free",3), 46 | (205,"free",3), 47 | (301,"free",2), 48 | (302,"free",2), 49 | (303,"free",2), 50 | (304,"free",3), 51 | (305,"free",3); 52 | 53 | insert into campers(first_name, last_name, age,room) values("Simo", "Sheytanov", 20,101), 54 | ("Roli", "Dimitrova", 27,102), 55 | ("RoYaL", "Yonkov", 25,301), 56 | ("Ivan", "Ivanov", 28,301), 57 | ("Alisa", "Terzieva", 25,102), 58 | ("Asya", "Ivanova", 26,102), 59 | ("Dimitar", "Verbov", 21,301), 60 | ("Iskren", "Ivanov", 28,302), 61 | ("Bojo", "Gevechanov", 28,302); 62 | 63 | insert into vehicles(driver_id,vehicle_type,passengers) values 64 | (1,"bus",20), 65 | (2,"van",10), 66 | (1,"van",10), 67 | (4,"car",5), 68 | (5,"car",5), 69 | (6,"car",4), 70 | (7,"car",3), 71 | (8,"bus",3); 72 | 73 | insert into routes(starting_point,end_point,leader_id,route_time) values 74 | ("Hotel Malyovitsa", "Malyovitsa Peak", 3, '02:00:00'), 75 | ("Hotel Malyovitsa", "Malyovitsa Hut", 3, '00:40:00'), 76 | ("Ribni Ezera Hut", "Rila Monastery", 3, '06:00:00'), 77 | ("Borovets", "Musala Peak", 4, '03:30:00'); -------------------------------------------------------------------------------- /06. Table Relations/Databases/joins_db.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE joins_db; 2 | USE joins_db; 3 | 4 | CREATE TABLE courses( 5 | id INT PRIMARY KEY AUTO_INCREMENT, 6 | name VARCHAR(20) NOT NULL 7 | ); 8 | 9 | CREATE TABLE students( 10 | id INT PRIMARY KEY AUTO_INCREMENT, 11 | name VARCHAR(20) NOT NULL, 12 | course_id INT, 13 | CONSTRAINT fk_course_id 14 | FOREIGN KEY (course_id) 15 | REFERENCES courses(id) 16 | ); 17 | 18 | INSERT INTO courses(id, name) VALUES (1, 'HTML5'),(2,'CSS3'), 19 | (3,'JavaScript'),(4,'PHP'),(5,'MySQL'); 20 | 21 | INSERT INTO students(id, name, course_id) 22 | VALUES (1,'Alice',1),(2,'Michael',1),(3,'Caroline',2),(4,'David',5),(5,'Emma',NULL); -------------------------------------------------------------------------------- /06. Table Relations/Table Relations Exercise.sql: -------------------------------------------------------------------------------- 1 | -- https://judge.softuni.bg/Contests/Practice/Index/605#0 2 | 3 | CREATE DATABASE `exercises`; 4 | USE `exercises`; 5 | 6 | -- 01. One-To-One Relationship 7 | -- Create two tables as follows. Use appropriate data types. 8 | /* 9 | persons 10 | person_id first_name salary passport_id 11 | 1 Roberto 43300.00 102 12 | 2 Tom 56100.00 103 13 | 3 Yana 60200.00 101 14 | 15 | passports 16 | passport_id passport_number 17 | 101 N34FG21B 18 | 102 K65LO4R7 19 | 103 ZE657QP2 20 | */ 21 | -- Insert the data from the example above. 22 | -- Alter table persons and make person_id a primary key. 23 | -- Create a foreign key between persons and passports by using passport_id column. 24 | -- Think about which passport field should be UNIQUE 25 | 26 | CREATE TABLE `persons` ( 27 | `person_id` INT UNSIGNED UNIQUE NOT NULL AUTO_INCREMENT, 28 | `first_name` VARCHAR(30) NOT NULL, 29 | `salary` DECIMAL(10, 2) NOT NULL DEFAULT 0, 30 | `passport_id` INT UNSIGNED NOT NULL UNIQUE 31 | ); 32 | 33 | CREATE TABLE `passports` ( 34 | `passport_id` INT UNSIGNED UNIQUE AUTO_INCREMENT PRIMARY KEY, 35 | `passport_number` VARCHAR(8) NOT NULL UNIQUE 36 | ) AUTO_INCREMENT=101; 37 | 38 | INSERT 39 | INTO `persons` (`first_name`, `salary`, `passport_id`) 40 | VALUES 41 | ('Roberto', 43300, 102), 42 | ('Tom', 56100, 103), 43 | ('Yana', 60200, 101); 44 | 45 | INSERT 46 | INTO `passports` (`passport_number`) 47 | VALUES ('N34FG21B'), ('K65LO4R7'), ('ZE657QP2'); 48 | 49 | ALTER TABLE `persons` 50 | ADD CONSTRAINT `pk_persons` 51 | PRIMARY KEY (`person_id`), 52 | ADD CONSTRAINT `fk_persons_passports` 53 | FOREIGN KEY(`passport_id`) 54 | REFERENCES `passports`(`passport_id`); 55 | 56 | 57 | -- 02. One-To-Many Relationship 58 | -- Create two tables as follows. Use appropriate data types. 59 | /* 60 | manufacturers 61 | manufacturer_id name established_on 62 | 1 BMW 01/03/1916 63 | 2 Tesla 01/01/2003 64 | 3 Lada 01/05/1966 65 | 66 | models 67 | model_id name manufacturer_id 68 | 101 X1 1 69 | 102 i6 1 70 | 103 Model S 2 71 | 104 Model X 2 72 | 105 Model 3 2 73 | 106 Nova 3 74 | */ 75 | -- Insert the data from the example above. 76 | -- Add primary and foreign keys. 77 | 78 | CREATE TABLE `manufacturers` ( 79 | `manufacturer_id` INT UNSIGNED UNIQUE NOT NULL AUTO_INCREMENT, 80 | `name` VARCHAR(30) UNIQUE NOT NULL, 81 | `established_on` DATE NOT NULL 82 | ); 83 | 84 | CREATE TABLE `models` ( 85 | `model_id` INT UNSIGNED UNIQUE NOT NULL AUTO_INCREMENT, 86 | `name` VARCHAR(30) NOT NULL, 87 | `manufacturer_id` INT UNSIGNED NOT NULL 88 | ) AUTO_INCREMENT=101; 89 | 90 | -- Data should be inserted here, but if we do so the data test in 91 | -- Judge fails because entries are not order as expected there so 92 | -- first we have to complete tables setup. 93 | 94 | ALTER TABLE `manufacturers` 95 | ADD CONSTRAINT `pk_manufacturers` 96 | PRIMARY KEY (`manufacturer_id`); 97 | 98 | ALTER TABLE `models` 99 | ADD CONSTRAINT `pk_models` 100 | PRIMARY KEY (`model_id`), 101 | ADD CONSTRAINT `fk_models_manufacturers` 102 | FOREIGN KEY (`manufacturer_id`) 103 | REFERENCES `manufacturers` (`manufacturer_id`); 104 | 105 | INSERT 106 | INTO `manufacturers` (`name`, `established_on`) 107 | VALUES 108 | ('BMW', '1916-03-01'), 109 | ('Tesla', '2003-01-01'), 110 | ('Lada', '1966-05-01'); 111 | 112 | INSERT 113 | INTO `models` (`name`, `manufacturer_id`) 114 | VALUES 115 | ('X1', 1), 116 | ('i6', 1), 117 | ('Model S', 2), 118 | ('Model X', 2), 119 | ('Model 3', 2), 120 | ('Nova', 3); 121 | 122 | -- Data test query used in Judge 123 | SELECT 124 | man.manufacturer_id, 125 | man.name, 126 | DATE(man.established_on), 127 | m.model_id, 128 | m.name 129 | FROM 130 | manufacturers man 131 | INNER JOIN 132 | models m ON man.manufacturer_id = m.manufacturer_id 133 | ORDER BY man.manufacturer_id; 134 | 135 | 136 | -- 03. Many-To-Many Relationship 137 | -- Create three tables as follows. Use appropriate data types. 138 | /* 139 | students 140 | student_id name 141 | 1 Mila 142 | 2 Toni 143 | 3 Ron 144 | 145 | exams 146 | exam_id name 147 | 101 Spring MVC 148 | 102 Neo4j 149 | 103 Oracle 11g 150 | 151 | students_exams 152 | student_id exam_id 153 | 1 101 154 | 1 102 155 | 2 101 156 | 3 103 157 | 2 102 158 | 2 103 159 | */ 160 | -- Insert the data from the example above. 161 | -- Add primary keys and foreign keys. 162 | -- Have in mind that table student_exams should have a composite primary key. 163 | 164 | CREATE TABLE `students` ( 165 | `student_id` INT UNSIGNED UNIQUE NOT NULL AUTO_INCREMENT, 166 | `name` VARCHAR(30) NOT NULL 167 | ); 168 | 169 | CREATE TABLE `exams` ( 170 | `exam_id` INT UNSIGNED UNIQUE NOT NULL AUTO_INCREMENT, 171 | `name` VARCHAR(30) NOT NULL 172 | ) AUTO_INCREMENT=101; 173 | 174 | CREATE TABLE `students_exams` ( 175 | `student_id` INT UNSIGNED NOT NULL, 176 | `exam_id` INT UNSIGNED NOT NULL 177 | ); 178 | 179 | -- Data should be inserted here, but by doing so the solution doesn't compile 180 | -- in Judge: "Object reference not set to an instance of an object.", 181 | -- so first tables setup should be finished: 182 | 183 | ALTER TABLE `students` 184 | ADD CONSTRAINT `pk_students` 185 | PRIMARY KEY (`student_id`); 186 | 187 | ALTER TABLE `exams` 188 | ADD CONSTRAINT `pk_exams` 189 | PRIMARY KEY (`exam_id`); 190 | 191 | ALTER TABLE `students_exams` 192 | ADD CONSTRAINT `pk_students_exams` 193 | PRIMARY KEY (`student_id`, `exam_id`), 194 | ADD CONSTRAINT `fk_students_exams_students` 195 | FOREIGN KEY (`student_id`) 196 | REFERENCES `students` (`student_id`), 197 | ADD CONSTRAINT `fk_students_exams_exams` 198 | FOREIGN KEY (`exam_id`) 199 | REFERENCES `exams` (`exam_id`); 200 | 201 | INSERT 202 | INTO `students` 203 | (`name`) 204 | VALUES 205 | ('Mila'), 206 | ('Toni'), 207 | ('Ron'); 208 | 209 | INSERT 210 | INTO `exams` 211 | (`name`) 212 | VALUES 213 | ('Spring MVC'), 214 | ('Neo4j'), 215 | ('Oracle 11g'); 216 | 217 | INSERT 218 | INTO `students_exams` 219 | VALUES 220 | (1, 101), 221 | (1, 102), 222 | (2, 101), 223 | (3, 103), 224 | (2, 102), 225 | (2, 103); 226 | 227 | 228 | -- 04. Self-Referencing 229 | -- Create a single table as follows. Use appropriate data types. 230 | /* 231 | teachers 232 | teacher_id name manager_id 233 | 101 John 234 | 102 Maya 106 235 | 103 Silvia 106 236 | 104 Ted 105 237 | 105 Mark 101 238 | 106 Greta 101 239 | */ 240 | -- Insert the data from the example above. 241 | -- Add primary keys and foreign keys. 242 | -- The foreign key should be between manager_id and teacher_id. 243 | 244 | CREATE TABLE `teachers` ( 245 | `teacher_id` INT UNSIGNED NOT NULL UNIQUE AUTO_INCREMENT, 246 | `name` VARCHAR(30) NOT NULL, 247 | `manager_id` INT UNSIGNED DEFAULT NULL 248 | ) AUTO_INCREMENT=101; 249 | 250 | INSERT 251 | INTO `teachers` 252 | (`name`, `manager_id`) 253 | VALUES 254 | ('John', NULL), 255 | ('Maya', 106), 256 | ('Silvia', 106), 257 | ('Ted', 105), 258 | ('Mark', 101), 259 | ('Greta', 101); 260 | 261 | ALTER TABLE `teachers` 262 | ADD CONSTRAINT `pk_teachers` 263 | PRIMARY KEY (`teacher_id`), 264 | ADD CONSTRAINT `fk_teacher_manager_id` 265 | FOREIGN KEY (`manager_id`) 266 | REFERENCES `teachers`(`teacher_id`); 267 | 268 | 269 | -- 05. Online Store Database 270 | CREATE DATABASE `online_store`; 271 | USE `online_store`; 272 | 273 | CREATE TABLE `item_types` ( 274 | `item_type_id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT, 275 | `name` VARCHAR(50) NOT NULL 276 | ); 277 | 278 | CREATE TABLE `items` ( 279 | `item_id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT, 280 | `name` VARCHAR(50) NOT NULL, 281 | `item_type_id` INT NOT NULL, 282 | CONSTRAINT `fk_items_item_types` 283 | FOREIGN KEY (`item_type_id`) 284 | REFERENCES `item_types` (`item_type_id`) 285 | ); 286 | 287 | CREATE TABLE `cities` ( 288 | `city_id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT, 289 | `name` VARCHAR(50) NOT NULL 290 | ); 291 | 292 | CREATE TABLE `customers` ( 293 | `customer_id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT, 294 | `name` VARCHAR(50) NOT NULL, 295 | `birthday` DATE, 296 | `city_id` INT NOT NULL, 297 | CONSTRAINT `fk_customers_cities` 298 | FOREIGN KEY (`city_id`) 299 | REFERENCES `cities` (`city_id`) 300 | ); 301 | 302 | CREATE TABLE `orders` ( 303 | `order_id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT, 304 | `customer_id` INT NOT NULL, 305 | CONSTRAINT `fk_orders_customers` 306 | FOREIGN KEY (`customer_id`) 307 | REFERENCES `customers` (`customer_id`) 308 | ); 309 | 310 | CREATE TABLE `order_items` ( 311 | `order_id` INT NOT NULL, 312 | `item_id` INT NOT NULL, 313 | CONSTRAINT `pk_order_items` 314 | PRIMARY KEY (`order_id` , `item_id`), 315 | CONSTRAINT `fk_order_items_orders` 316 | FOREIGN KEY (`order_id`) 317 | REFERENCES `orders` (`order_id`), 318 | CONSTRAINT `fk_order_items_items` 319 | FOREIGN KEY (`item_id`) 320 | REFERENCES `items` (`item_id`) 321 | ); 322 | 323 | 324 | -- 06. University Database 325 | CREATE DATABASE `university`; 326 | USE `university`; 327 | 328 | CREATE TABLE `subjects` ( 329 | `subject_id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT, 330 | `subject_name` VARCHAR(50) NOT NULL 331 | ); 332 | 333 | CREATE TABLE `majors` ( 334 | `major_id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT, 335 | `name` VARCHAR(50) NOT NULL 336 | ); 337 | 338 | CREATE TABLE `students` ( 339 | `student_id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT, 340 | `student_number` VARCHAR(12) NOT NULL, 341 | `student_name` VARCHAR(50) NOT NULL, 342 | `major_id` INT NOT NULL, 343 | CONSTRAINT `fk_students_majors` 344 | FOREIGN KEY (`major_id`) 345 | REFERENCES `majors` (`major_id`) 346 | ); 347 | 348 | CREATE TABLE `payments` ( 349 | `payment_id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT, 350 | `payment_date` DATE NOT NULL, 351 | `payment_amount` DECIMAL(8, 2) NOT NULL, 352 | `student_id` INT NOT NULL, 353 | CONSTRAINT `fk_payments_students` 354 | FOREIGN KEY (`student_id`) 355 | REFERENCES `students` (`student_id`) 356 | ); 357 | 358 | CREATE TABLE `agenda` ( 359 | `student_id` INT NOT NULL, 360 | `subject_id` INT NOT NULL, 361 | CONSTRAINT `pk_agenda` PRIMARY KEY (`student_id` , `subject_id`), 362 | CONSTRAINT `fk_agendar_students` FOREIGN KEY (`student_id`) 363 | REFERENCES `students` (`student_id`), 364 | CONSTRAINT `fk_agenda_subjects` FOREIGN KEY (`subject_id`) 365 | REFERENCES `subjects` (`subject_id`) 366 | ); 367 | 368 | 369 | -- 09. Peaks in Rila 370 | -- Display all peaks for "Rila" mountain_range. 371 | -- Include: 372 | -- mountain_range 373 | -- peak_name 374 | -- peak_elevation 375 | -- Peaks should be sorted by peak_elevation descending. 376 | 377 | USE `geography`; 378 | 379 | SELECT 380 | m.mountain_range, 381 | p.peak_name, 382 | p.elevation AS 'peak_elevation' 383 | FROM 384 | `mountains` AS m 385 | JOIN 386 | `peaks` AS p ON m.id = p.mountain_id 387 | WHERE 388 | m.mountain_range = 'Rila' 389 | ORDER BY p.elevation DESC; 390 | 391 | -------------------------------------------------------------------------------- /06. Table Relations/Table Relations Lab.sql: -------------------------------------------------------------------------------- 1 | -- https://judge.softuni.bg/Contests/Practice/Index/748#0 2 | 3 | -- Get familiar with the camp database. 4 | -- You will use it in the following exercises bellow. 5 | 6 | USE `camp`; 7 | 8 | -- 1. Mountains and Peaks 9 | -- Write a query to create two tables – mountains and peaks and link their fields properly. 10 | -- Tables should have: 11 | -- Mountains: 12 | -- id 13 | -- name 14 | -- Peaks: 15 | -- id 16 | -- name 17 | -- mountain_id 18 | 19 | CREATE TABLE `mountains` ( 20 | `id` INT UNSIGNED UNIQUE AUTO_INCREMENT PRIMARY KEY, 21 | `name` VARCHAR(50) NOT NULL 22 | ); 23 | 24 | CREATE TABLE `peaks` ( 25 | `id` INT UNSIGNED UNIQUE AUTO_INCREMENT PRIMARY KEY, 26 | `name` VARCHAR(50) NOT NULL, 27 | `mountain_id` INT UNSIGNED UNIQUE, 28 | CONSTRAINT `fk_peaks_mountains` FOREIGN KEY (`mountain_id`) 29 | REFERENCES `mountains` (`id`) 30 | ); 31 | 32 | 33 | -- 2. Books and Authors 34 | -- Write a query to create a one-to-many relationship between a table, 35 | -- holding information about books and other -about authors, so that when 36 | -- an author gets removed from the database all his books are deleted too. 37 | -- The tables should have: 38 | -- Books 39 | -- id 40 | -- name 41 | -- author_id 42 | -- Authors 43 | -- id 44 | -- name 45 | 46 | CREATE TABLE `authors` ( 47 | `id` INT UNSIGNED UNIQUE AUTO_INCREMENT PRIMARY KEY, 48 | `name` VARCHAR(50) NOT NULL 49 | ); 50 | 51 | CREATE TABLE `books` ( 52 | `id` INT UNSIGNED UNIQUE AUTO_INCREMENT PRIMARY KEY, 53 | `name` VARCHAR(50) NOT NULL, 54 | `author_id` INT UNSIGNED, 55 | CONSTRAINT `fk_books_authors` FOREIGN KEY (`author_id`) 56 | REFERENCES `authors` (`id`) 57 | ON DELETE CASCADE 58 | ); 59 | 60 | -- Demo 61 | INSERT INTO `authors` (`name`) VALUES ("Ivan"), ("Pesho"), ("Gosho"); 62 | INSERT INTO `books` (`name`, `author_id`) VALUES ("Book 1", 1), ("Book 2", 2), ("Book 3", 1); 63 | DELETE FROM `authors` WHERE `id`=1; 64 | SELECT * FROM `authors`; 65 | SELECT * FROM `books`; 66 | 67 | 68 | -- 3. Trip Organization 69 | -- Write a query to retrieve information about the SoftUni camp’s transportation organization. 70 | -- Get information about the people who drive(name and age) and their vehicle type. 71 | 72 | SELECT 73 | `driver_id`, 74 | `vehicle_type`, 75 | CONCAT(`c`.`first_name`, ' ', `c`.`last_name`) AS `driver_name` 76 | FROM 77 | `vehicles` AS `v` 78 | JOIN 79 | `campers` AS `c` ON `v`.`driver_id` = `c`.`id`; 80 | 81 | 82 | -- 4. SoftUni Hiking 83 | -- Get information about the hiking routes and their leaders – name and id. 84 | 85 | SELECT 86 | `starting_point` AS 'route_starting_point', 87 | `end_point` AS 'route_ending_point', 88 | `leader_id`, 89 | CONCAT(`c`.`first_name`, ' ', `c`.`last_name`) AS `leader_name` 90 | FROM 91 | `routes` AS `r` 92 | JOIN 93 | `campers` AS `c` ON `r`.`leader_id` = `c`.`id`; 94 | 95 | 96 | -- 5. Project Management DB * 97 | -- Write a query to create a project management db according to the given E/R Diagram 98 | 99 | CREATE DATABASE `company`; 100 | USE `company`; 101 | 102 | CREATE TABLE `projects` ( 103 | `id` INT(11) UNSIGNED UNIQUE AUTO_INCREMENT PRIMARY KEY, 104 | `client_id` INT(11) UNSIGNED, 105 | `project_lead_id` INT(11) UNSIGNED 106 | ); 107 | 108 | CREATE TABLE `clients` ( 109 | `id` INT(11) UNSIGNED UNIQUE AUTO_INCREMENT PRIMARY KEY, 110 | `client_name` VARCHAR(100) NOT NULL, 111 | `project_id` INT(11) UNSIGNED 112 | ); 113 | 114 | CREATE TABLE `employees` ( 115 | `id` INT(11) UNSIGNED UNIQUE AUTO_INCREMENT PRIMARY KEY, 116 | `first_name` VARCHAR(30) NOT NULL, 117 | `last_name` VARCHAR(30) NOT NULL, 118 | `project_id` INT(11) UNSIGNED 119 | ); 120 | 121 | ALTER TABLE `projects` 122 | ADD CONSTRAINT `fk_projects_clients` 123 | FOREIGN KEY (`client_id`) 124 | REFERENCES `clients` (`id`), 125 | ADD CONSTRAINT `fk_projects_employees` 126 | FOREIGN KEY (`project_lead_id`) 127 | REFERENCES `employees` (`id`); 128 | 129 | ALTER TABLE `clients` 130 | ADD CONSTRAINT `fk_clients_projects` 131 | FOREIGN KEY (`project_id`) 132 | REFERENCES `projects` (`id`); 133 | 134 | ALTER TABLE `employees` 135 | ADD CONSTRAINT `fk_employees_projects` 136 | FOREIGN KEY (`project_id`) 137 | REFERENCES `projects` (`id`); 138 | -------------------------------------------------------------------------------- /07. Subqueries And Joins/07. Joins, Subqueries and Indices-Lab.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/07. Subqueries And Joins/07. Joins, Subqueries and Indices-Lab.docx -------------------------------------------------------------------------------- /07. Subqueries And Joins/07. Joins-Subqueries-and-Indices-Exercise.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/07. Subqueries And Joins/07. Joins-Subqueries-and-Indices-Exercise.docx -------------------------------------------------------------------------------- /07. Subqueries And Joins/07. Joins-Subqueries-and-Indices.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/07. Subqueries And Joins/07. Joins-Subqueries-and-Indices.pdf -------------------------------------------------------------------------------- /07. Subqueries And Joins/Databases/bank_db.sql: -------------------------------------------------------------------------------- 1 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 2 | /*!40101 SET NAMES utf8mb4 */; 3 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 4 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 5 | 6 | 7 | -- Dumping structure for table bank.accounts 8 | DROP TABLE IF EXISTS `accounts`; 9 | CREATE TABLE IF NOT EXISTS `accounts` ( 10 | `id` int(11) NOT NULL, 11 | `account_holder_id` int(11) NOT NULL, 12 | `balance` decimal(19,4) DEFAULT '0.0000', 13 | PRIMARY KEY (`id`), 14 | KEY `fk_accounts_account_holders` (`account_holder_id`), 15 | CONSTRAINT `fk_accounts_account_holders` FOREIGN KEY (`account_holder_id`) REFERENCES `account_holders` (`id`) 16 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 17 | 18 | -- Dumping data for table bank.accounts: ~18 rows (approximately) 19 | /*!40000 ALTER TABLE `accounts` DISABLE KEYS */; 20 | INSERT INTO `accounts` (`id`, `account_holder_id`, `balance`) VALUES 21 | (1, 1, 123.1200), 22 | (2, 3, 4354.2300), 23 | (3, 12, 6546543.2300), 24 | (4, 9, 15345.6400), 25 | (5, 11, 36521.2000), 26 | (6, 8, 5436.3400), 27 | (7, 10, 565649.2000), 28 | (8, 11, 999453.5000), 29 | (9, 1, 5349758.2300), 30 | (10, 2, 543.3000), 31 | (11, 3, 10.2000), 32 | (12, 7, 245656.2300), 33 | (13, 5, 5435.3200), 34 | (14, 4, 1.2300), 35 | (15, 6, 0.1900), 36 | (16, 2, 5345.3400), 37 | (17, 11, 76653.2000), 38 | (18, 1, 235469.8900); 39 | /*!40000 ALTER TABLE `accounts` ENABLE KEYS */; 40 | 41 | 42 | -- Dumping structure for table bank.account_holders 43 | DROP TABLE IF EXISTS `account_holders`; 44 | CREATE TABLE IF NOT EXISTS `account_holders` ( 45 | `id` int(11) NOT NULL, 46 | `first_name` varchar(50) NOT NULL, 47 | `last_name` varchar(50) NOT NULL, 48 | `ssn` char(10) NOT NULL, 49 | PRIMARY KEY (`id`) 50 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 51 | 52 | -- Dumping data for table bank.account_holders: ~12 rows (approximately) 53 | /*!40000 ALTER TABLE `account_holders` DISABLE KEYS */; 54 | INSERT INTO `account_holders` (`id`, `first_name`, `last_name`, `ssn`) VALUES 55 | (1, 'Susan', 'Cane', '1234567890'), 56 | (2, 'Kim', 'Novac', '1234567890'), 57 | (3, 'Jimmy', 'Henderson', '1234567890'), 58 | (4, 'Steve', 'Stevenson', '1234567890'), 59 | (5, 'Bjorn', 'Sweden', '1234567890'), 60 | (6, 'Kiril', 'Petrov', '1234567890'), 61 | (7, 'Petar', 'Kirilov', '1234567890'), 62 | (8, 'Michka', 'Tsekova', '1234567890'), 63 | (9, 'Zlatina', 'Pateva', '1234567890'), 64 | (10, 'Monika', 'Miteva', '1234567890'), 65 | (11, 'Zlatko', 'Zlatyov', '1234567890'), 66 | (12, 'Petko', 'Petkov Junior', '1234567890'); 67 | /*!40000 ALTER TABLE `account_holders` ENABLE KEYS */; 68 | /*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; 69 | /*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; 70 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -------------------------------------------------------------------------------- /07. Subqueries And Joins/Subqueries And Joins Exercise.sql: -------------------------------------------------------------------------------- 1 | -- https://judge.softuni.bg/Contests/Compete/Index/606#0 2 | 3 | USE `soft_uni`; 4 | 5 | -- 01. Employee Address 6 | -- Write a query that selects: 7 | -- * employee_id 8 | -- * job_title 9 | -- * address_id 10 | -- * address_text 11 | -- Return the first 5 rows sorted by address_id in ascending order. 12 | 13 | SELECT 14 | e.employee_id, e.job_title, e.address_id, a.address_text 15 | FROM 16 | `employees` AS e 17 | JOIN 18 | `addresses` AS a ON e.address_id = a.address_id 19 | ORDER BY e.address_id 20 | LIMIT 5; 21 | 22 | 23 | -- 02. Addresses with Towns 24 | -- Write a query that selects: 25 | -- * first_name 26 | -- * last_name 27 | -- * town 28 | -- * address_text 29 | -- Sorted by first_name in ascending order then by last_name. 30 | -- Select first 5 employees. 31 | 32 | SELECT 33 | e.first_name, e.last_name, t.name AS 'town', a.address_text 34 | FROM 35 | `employees` AS e 36 | JOIN 37 | `addresses` AS a ON e.address_id = a.address_id 38 | JOIN 39 | `towns` AS t ON a.town_id = t.town_id 40 | ORDER BY e.first_name , e.last_name 41 | LIMIT 5; 42 | 43 | 44 | -- 03. Sales Employee 45 | -- Write a query that selects: 46 | -- * employee_id 47 | -- * first_name 48 | -- * last_name 49 | -- * department_name 50 | -- Sorted by employee_id in descending order. 51 | -- Select only employees from “Sales” department. 52 | 53 | SELECT 54 | e.employee_id, e.first_name, e.last_name, d.name 55 | FROM 56 | `employees` AS e 57 | JOIN 58 | `departments` AS d ON e.department_id = d.department_id 59 | WHERE 60 | d.name = 'Sales' 61 | ORDER BY e.employee_id DESC; 62 | 63 | -- 04. Employee Departments 64 | -- Write a query that selects: 65 | -- * employee_id 66 | -- * first_name 67 | -- * salary 68 | -- * department_name 69 | -- Filter only employees with salary higher than 15000. 70 | -- Return the first 5 rows sorted by department_id in descending order. 71 | 72 | SELECT 73 | e.employee_id, e.first_name, e.salary, d.name 74 | FROM 75 | `employees` AS e 76 | JOIN 77 | `departments` AS d ON e.department_id = d.department_id 78 | WHERE 79 | e.salary > 15000 80 | ORDER BY d.department_id DESC 81 | LIMIT 5; 82 | 83 | 84 | -- 05. Employees Without Project 85 | -- Write a query that selects: 86 | -- * employee_id 87 | -- * first_name 88 | -- Filter only employees without a project. 89 | -- Return the first 3 rows sorted by employee_id in descending order. 90 | 91 | SELECT 92 | e.employee_id, e.first_name 93 | FROM 94 | `employees` AS e 95 | LEFT JOIN 96 | `employees_projects` AS ep ON e.employee_id = ep.employee_id 97 | WHERE 98 | ep.project_id IS NULL 99 | ORDER BY e.employee_id DESC 100 | LIMIT 3; 101 | 102 | 103 | -- 06. Employees Hired After 104 | -- Write a query that selects: 105 | -- * first_name 106 | -- * last_name 107 | -- * hire_date 108 | -- * dept_name 109 | -- Filter only employees with hired after 1/1/1999 and 110 | -- are from either "Sales" or "Finance" departments. 111 | -- Sorted by hire_date (ascending). 112 | 113 | SELECT 114 | e.first_name, e.last_name, e.hire_date, d.name 115 | FROM 116 | `employees` AS e 117 | JOIN 118 | `departments` AS d ON e.department_id = d.department_id 119 | WHERE 120 | d.name IN ('Sales' , 'Finance') 121 | AND DATE(e.hire_date) > '1999/1/1' 122 | ORDER BY e.hire_date; 123 | 124 | 125 | -- 07. Employees with Project 126 | -- Write a query that selects: 127 | -- * employee_id 128 | -- * first_name 129 | -- * project_name 130 | -- Filter only employees with a project which has started 131 | -- after 13.08.2002 and it is still ongoing (no end date). 132 | -- Return the first 5 rows sorted by first_name then by 133 | -- project_name both in ascending order. 134 | 135 | SELECT 136 | e.employee_id, e.first_name, p.name AS 'project_name' 137 | FROM 138 | `employees` AS e 139 | JOIN 140 | `employees_projects` AS ep ON ep.employee_id = e.employee_id 141 | JOIN 142 | `projects` AS p ON ep.project_id = p.project_id 143 | WHERE 144 | DATE(p.start_date) > '2002-08-13' 145 | AND p.end_date IS NULL 146 | ORDER BY e.first_name , p.name 147 | LIMIT 5; 148 | 149 | 150 | -- 08. Employee 24 151 | -- Write a query that selects: 152 | -- * employee_id 153 | -- * first_name 154 | -- * project_name 155 | -- Filter all the projects of employees with id 24. 156 | -- If the project has started after 2005 inclusively the return value should be NULL. 157 | -- Sort result by project_name alphabetically. 158 | 159 | SELECT 160 | e.employee_id, 161 | e.first_name, 162 | IF(YEAR(p.start_date) >= 2005, 163 | NULL, 164 | p.name) AS 'project_name' 165 | FROM 166 | `employees` AS e 167 | JOIN 168 | `employees_projects` AS ep ON ep.employee_id = e.employee_id 169 | JOIN 170 | `projects` AS p ON ep.project_id = p.project_id 171 | WHERE 172 | e.employee_id = 24 173 | ORDER BY p.name; 174 | 175 | 176 | -- 09. Employee Manager 177 | -- Write a query that selects: 178 | -- * employee_id 179 | -- * first_name 180 | -- * manager_id 181 | -- * manager_name 182 | -- Filter all employees with a manager who has id equals to 3 or 7. 183 | -- Return the all rows sorted by employee first_name in ascending order. 184 | 185 | SELECT 186 | e.employee_id, e.first_name, e.manager_id, m.first_name 187 | FROM 188 | `employees` AS e 189 | JOIN 190 | `employees` AS m ON e.manager_id = m.employee_id 191 | WHERE 192 | e.manager_id IN (3 , 7) 193 | ORDER BY e.first_name; 194 | 195 | 196 | -- 10. Employee Summary 197 | -- Write a query that selects: 198 | -- * employee_id 199 | -- * employee_name 200 | -- * manager_name 201 | -- * department_name 202 | -- Show first 5 employees (only for employees who has a manager) with their managers 203 | -- and the departments which they are in (show the departments of the employees). 204 | -- Order by employee_id. 205 | 206 | SELECT 207 | e.employee_id, 208 | CONCAT_WS(' ', e.first_name, e.last_name) AS 'employee_name', 209 | CONCAT_WS(' ', m.first_name, m.last_name) AS 'manager_name', 210 | d.name AS 'department_name' 211 | FROM 212 | `employees` AS e 213 | JOIN 214 | `employees` AS m ON e.manager_id = m.employee_id 215 | JOIN 216 | `departments` AS d ON e.department_id = d.department_id 217 | ORDER BY e.employee_id 218 | LIMIT 5; 219 | 220 | 221 | -- 11. Min Average Salary 222 | -- Write a query that return the value of the lowest average salary of all departments. 223 | -- * min_average_salary 224 | 225 | SELECT 226 | AVG(e.salary) AS 'min_average_salary' 227 | FROM 228 | `employees` AS e 229 | GROUP BY e.department_id 230 | ORDER BY `min_average_salary` 231 | LIMIT 1; 232 | 233 | 234 | 235 | USE `geography`; 236 | 237 | -- 12. Highest Peaks in Bulgaria 238 | -- Write a query that selects: 239 | -- * country_code 240 | -- * mountain_range 241 | -- * peak_name 242 | -- * elevation 243 | -- Filter all peaks in Bulgaria with elevation over 2835. 244 | -- Return the all rows sorted by elevation in descending order. 245 | 246 | SELECT 247 | c.country_code, m.mountain_range, p.peak_name, p.elevation 248 | FROM 249 | `countries` AS c 250 | JOIN 251 | `mountains_countries` AS mc ON c.country_code = mc.country_code 252 | JOIN 253 | `mountains` AS m ON m.id = mc.mountain_id 254 | JOIN 255 | `peaks` AS p ON p.mountain_id = mc.mountain_id 256 | WHERE 257 | c.country_name = 'Bulgaria' 258 | AND p.elevation > 2835 259 | ORDER BY p.elevation DESC; 260 | 261 | 262 | -- 13. Count Mountain Ranges 263 | -- Write a query that selects: 264 | -- * country_code 265 | -- * mountain_range 266 | -- Filter the count of the mountain ranges in the United States, Russia and Bulgaria. 267 | -- Sort result by mountain_range count in decreasing order. 268 | 269 | SELECT 270 | c.country_code, COUNT(mc.mountain_id) AS 'mountain_range' 271 | FROM 272 | `countries` AS c 273 | JOIN 274 | `mountains_countries` AS mc ON c.country_code = mc.country_code 275 | WHERE 276 | c.country_name IN ('United States' , 'Russia', 'Bulgaria') 277 | GROUP BY c.country_code 278 | ORDER BY `mountain_range` DESC; 279 | 280 | 281 | -- 14. Countries with Rivers 282 | -- Write a query that selects: 283 | -- * country_name 284 | -- * river_name 285 | -- Find the first 5 countries with or without rivers in Africa. 286 | -- Sort them by country_name in ascending order. 287 | 288 | SELECT 289 | c.country_name, r.river_name 290 | FROM 291 | `countries` AS c 292 | LEFT JOIN 293 | `countries_rivers` AS cr ON c.country_code = cr.country_code 294 | LEFT JOIN 295 | `rivers` AS r ON r.id = cr.river_id 296 | JOIN 297 | `continents` AS cn ON cn.continent_code = c.continent_code 298 | WHERE 299 | cn.continent_name = 'Africa' 300 | ORDER BY c.country_name 301 | LIMIT 5; 302 | 303 | 304 | -- 15. *Continents and Currencies 305 | -- Write a query that selects: 306 | -- * continent_code 307 | -- * currency_code 308 | -- * currency_usage 309 | -- Find all continents and their most used currency. 310 | -- Filter any currency that is used in only one country. 311 | -- Sort your results by continent_code and currency_code. 312 | 313 | SELECT 314 | c.continent_code, 315 | c.currency_code, 316 | COUNT(*) AS 'currency_usage' 317 | FROM 318 | `countries` AS c 319 | GROUP BY c.continent_code , c.currency_code 320 | HAVING `currency_usage` > 1 321 | AND `currency_usage` = (SELECT 322 | COUNT(*) AS cn 323 | FROM 324 | `countries` AS c2 325 | WHERE 326 | c2.continent_code = c.continent_code 327 | GROUP BY c2.currency_code 328 | ORDER BY cn DESC 329 | LIMIT 1) 330 | ORDER BY c.continent_code , c.continent_code; 331 | 332 | 333 | -- 16. Countries without any Mountains 334 | -- Find all the count of all countries which don’t have a mountain. 335 | SELECT 336 | COUNT(*) as 'country_count' 337 | FROM 338 | (SELECT 339 | mc.country_code AS 'mc_country_code' 340 | FROM 341 | `mountains_countries` AS mc 342 | GROUP BY mc.country_code) AS d 343 | RIGHT JOIN 344 | `countries` AS c ON c.country_code = d.mc_country_code 345 | WHERE 346 | d.mc_country_code IS NULL; 347 | 348 | 349 | -- 17. Highest Peak and Longest River by Country 350 | -- For each country, find the elevation of the highest peak and the length 351 | -- of the longest river, sorted by the highest peak_elevation (from highest 352 | -- to lowest), then by the longest river_length (from longest to smallest), 353 | -- then by country_name (alphabetically). Display NULL when no data is 354 | -- available in some of the columns. Limit only the first 5 rows. 355 | -- country_name, highest_peak_elevation, longest_river_length 356 | 357 | SELECT 358 | c.country_name, 359 | MAX(p.elevation) AS 'highest_peak_elevation', 360 | MAX(r.length) AS 'longest_river_length' 361 | FROM 362 | `countries` AS c 363 | LEFT JOIN 364 | `mountains_countries` AS mc ON c.country_code = mc.country_code 365 | LEFT JOIN 366 | `peaks` AS p ON mc.mountain_id = p.mountain_id 367 | LEFT JOIN 368 | `countries_rivers` AS cr ON c.country_code = cr.country_code 369 | LEFT JOIN 370 | `rivers` AS r ON cr.river_id = r.id 371 | GROUP BY c.country_name 372 | ORDER BY `highest_peak_elevation` DESC , `longest_river_length` DESC , c.country_name 373 | LIMIT 5; -------------------------------------------------------------------------------- /07. Subqueries And Joins/Subqueries And Joins Lab.sql: -------------------------------------------------------------------------------- 1 | USE `soft_uni`; 2 | 3 | -- 1. Managers 4 | -- Write a query to retrieve information about the managers: 5 | -- employee_id, full_name, deparment_id and department_name. 6 | -- Select first 5 deparments ordered by employee_id. 7 | 8 | SELECT 9 | e.employee_id, 10 | CONCAT_WS(' ', e.first_name, e.last_name) AS 'full_name', 11 | d.department_id, 12 | d.name AS 'department_name' 13 | FROM 14 | `departments` AS d 15 | INNER JOIN 16 | `employees` AS e ON e.employee_id = d.manager_id 17 | ORDER BY e.employee_id 18 | LIMIT 5; 19 | 20 | 21 | -- 2. Towns and Addresses 22 | -- Write a query to get information about adresses in the database, 23 | -- which are in San Francisco, Sofia or Carnation. Retrieve town_id, 24 | -- town_name, address_text. Order the result by town_id, then by address_id. 25 | 26 | SELECT 27 | a.town_id, t.name AS 'town_name', a.address_text 28 | FROM 29 | `addresses` AS a 30 | JOIN 31 | `towns` AS t ON a.town_id = t.town_id 32 | WHERE 33 | t.name IN ('San Francisco' , 'Sofia', 'Carnation') 34 | ORDER BY t.town_id , a.address_id; 35 | 36 | 37 | -- 3. Employees Without Managers 38 | -- Write a get information about employee_id, first_name, last_name, 39 | -- department_id and salary about all employees who don’t have a manager. 40 | 41 | SELECT 42 | e.employee_id, 43 | e.first_name, 44 | e.last_name, 45 | e.department_id, 46 | e.salary 47 | FROM 48 | `employees` AS e 49 | WHERE 50 | ISNULL(e.manager_id); 51 | 52 | 53 | -- 4. Higher Salary 54 | -- Write a query to count the number of employees who 55 | -- receive salary higher than the average. 56 | 57 | SELECT 58 | COUNT(e.employee_id) AS 'count' 59 | FROM 60 | `employees` AS e 61 | WHERE 62 | e.salary > (SELECT AVG(`salary`) FROM `employees`); 63 | -------------------------------------------------------------------------------- /08. Functions, Triggers and Transactions/08. Functions-Triggers-And-Transactions-Exercise.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/08. Functions, Triggers and Transactions/08. Functions-Triggers-And-Transactions-Exercise.docx -------------------------------------------------------------------------------- /08. Functions, Triggers and Transactions/08. Functions-Triggers-And-Transactions-Lab.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/08. Functions, Triggers and Transactions/08. Functions-Triggers-And-Transactions-Lab.docx -------------------------------------------------------------------------------- /08. Functions, Triggers and Transactions/08. Functions-Triggers-And-Transactions.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/08. Functions, Triggers and Transactions/08. Functions-Triggers-And-Transactions.pdf -------------------------------------------------------------------------------- /08. Functions, Triggers and Transactions/Databases/bank_db.sql: -------------------------------------------------------------------------------- 1 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 2 | /*!40101 SET NAMES utf8mb4 */; 3 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 4 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 5 | 6 | CREATE DATABASE IF NOT EXISTS `bank` /*!40100 DEFAULT CHARACTER SET utf8 */; 7 | USE `bank`; 8 | 9 | -- Dumping structure for table bank.accounts 10 | DROP TABLE IF EXISTS `accounts`; 11 | CREATE TABLE IF NOT EXISTS `accounts` ( 12 | `id` int(11) NOT NULL, 13 | `account_holder_id` int(11) NOT NULL, 14 | `balance` decimal(19,4) DEFAULT '0.0000', 15 | PRIMARY KEY (`id`), 16 | KEY `fk_accounts_account_holders` (`account_holder_id`), 17 | CONSTRAINT `fk_accounts_account_holders` FOREIGN KEY (`account_holder_id`) REFERENCES `account_holders` (`id`) 18 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 19 | 20 | -- Dumping data for table bank.accounts: ~18 rows (approximately) 21 | /*!40000 ALTER TABLE `accounts` DISABLE KEYS */; 22 | INSERT INTO `accounts` (`id`, `account_holder_id`, `balance`) VALUES 23 | (1, 1, 123.1200), 24 | (2, 3, 4354.2300), 25 | (3, 12, 6546543.2300), 26 | (4, 9, 15345.6400), 27 | (5, 11, 36521.2000), 28 | (6, 8, 5436.3400), 29 | (7, 10, 565649.2000), 30 | (8, 11, 999453.5000), 31 | (9, 1, 5349758.2300), 32 | (10, 2, 543.3000), 33 | (11, 3, 10.2000), 34 | (12, 7, 245656.2300), 35 | (13, 5, 5435.3200), 36 | (14, 4, 1.2300), 37 | (15, 6, 0.1900), 38 | (16, 2, 5345.3400), 39 | (17, 11, 76653.2000), 40 | (18, 1, 235469.8900); 41 | /*!40000 ALTER TABLE `accounts` ENABLE KEYS */; 42 | 43 | 44 | -- Dumping structure for table bank.account_holders 45 | DROP TABLE IF EXISTS `account_holders`; 46 | CREATE TABLE IF NOT EXISTS `account_holders` ( 47 | `id` int(11) NOT NULL, 48 | `first_name` varchar(50) NOT NULL, 49 | `last_name` varchar(50) NOT NULL, 50 | `ssn` char(10) NOT NULL, 51 | PRIMARY KEY (`id`) 52 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 53 | 54 | -- Dumping data for table bank.account_holders: ~12 rows (approximately) 55 | /*!40000 ALTER TABLE `account_holders` DISABLE KEYS */; 56 | INSERT INTO `account_holders` (`id`, `first_name`, `last_name`, `ssn`) VALUES 57 | (1, 'Susan', 'Cane', '1234567890'), 58 | (2, 'Kim', 'Novac', '1234567890'), 59 | (3, 'Jimmy', 'Henderson', '1234567890'), 60 | (4, 'Steve', 'Stevenson', '1234567890'), 61 | (5, 'Bjorn', 'Sweden', '1234567890'), 62 | (6, 'Kiril', 'Petrov', '1234567890'), 63 | (7, 'Petar', 'Kirilov', '1234567890'), 64 | (8, 'Michka', 'Tsekova', '1234567890'), 65 | (9, 'Zlatina', 'Pateva', '1234567890'), 66 | (10, 'Monika', 'Miteva', '1234567890'), 67 | (11, 'Zlatko', 'Zlatyov', '1234567890'), 68 | (12, 'Petko', 'Petkov Junior', '1234567890'); 69 | /*!40000 ALTER TABLE `account_holders` ENABLE KEYS */; 70 | /*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; 71 | /*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; 72 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -------------------------------------------------------------------------------- /08. Functions, Triggers and Transactions/Functions, Triggers and Transactions Lab.sql: -------------------------------------------------------------------------------- 1 | USE `soft_uni`; 2 | 3 | -- 1. Count Employees by Town 4 | -- Write a function ufn_count_employees_by_town(town_name) 5 | -- that accepts town_name as parameter and returns the count 6 | -- of employees who live in that town. 7 | 8 | CREATE FUNCTION ufn_count_employees_by_town(town_name VARCHAR(20)) 9 | RETURNS INT 10 | RETURN ( 11 | SELECT COUNT(e.employee_id) 12 | FROM `employees` AS e 13 | JOIN `addresses` AS a ON a.address_id = e.address_id 14 | JOIN `towns` AS t ON t.town_id = a.town_id 15 | WHERE t.name = town_name 16 | ); 17 | 18 | -- Demo 19 | SELECT ufn_count_employees_by_town('Sofia') AS 'count'; 20 | 21 | -- Cleanup 22 | DROP FUNCTION IF EXISTS ufn_count_employees_by_town; 23 | 24 | 25 | -- 2. Employees Promotion 26 | -- Write a stored procedure usp_raise_salaries(department_name) to 27 | -- raise the salary of all employees in given department as parameter by 5%. 28 | 29 | DELIMITER $$ 30 | CREATE PROCEDURE usp_raise_salaries(department_name VARCHAR(50)) 31 | BEGIN 32 | UPDATE `employees` AS e 33 | JOIN `departments` AS d ON e.department_id = d.department_id 34 | SET e.salary = e.salary * 1.05 35 | WHERE d.name = department_name; 36 | END $$ 37 | DELIMITER ; 38 | 39 | -- Demo 40 | DELIMITER $$ 41 | CREATE PROCEDURE usp_get_salary_by_department(department_name VARCHAR(50)) 42 | BEGIN 43 | SELECT 44 | e.employee_id, e.salary 45 | FROM 46 | `employees` AS e 47 | JOIN 48 | `departments` AS d ON e.department_id = d.department_id 49 | WHERE 50 | d.name = department_name; 51 | END $$ 52 | DELIMITER ; 53 | 54 | CALL usp_get_salary_by_department('Sales'); 55 | 56 | SET SQL_SAFE_UPDATES=0; 57 | CALL usp_raise_salaries('Sales'); 58 | SET SQL_SAFE_UPDATES=1; 59 | 60 | CALL usp_get_salary_by_department('Sales'); 61 | 62 | DROP PROCEDURE IF EXISTS usp_raise_salaries; 63 | DROP PROCEDURE IF EXISTS ufn_get_salary_by_department; 64 | 65 | 66 | -- 3. Employees Promotion By ID 67 | -- Write a stored procedure usp_raise_salary_by_id(id) that raises 68 | -- a given employee’s salary (by id as parameter) by 5%. Consider 69 | -- that you cannot promote an employee that doesn’t exist – if that 70 | -- happens, no changes to the database should be made. 71 | 72 | DELIMITER $$ 73 | CREATE PROCEDURE usp_raise_salary_by_id(id INT(10)) 74 | BEGIN 75 | UPDATE `employees` AS e 76 | SET e.salary = e.salary * 1.05 77 | WHERE e.employee_id = id; 78 | END $$ 79 | DELIMITER ; 80 | 81 | -- With transaction 82 | DELIMITER $$ 83 | CREATE PROCEDURE usp_raise_salary_by_id(id INT(10)) 84 | BEGIN 85 | START TRANSACTION; 86 | IF((SELECT COUNT(e.employee_id) 87 | FROM `employees` as e 88 | WHERE e.employee_id LIKE id)<>1) 89 | THEN ROLLBACK; 90 | ELSE 91 | UPDATE `employees` AS e 92 | SET e.salary = e.salary * 1.05 93 | WHERE e.employee_id = id; 94 | END IF; 95 | END $$ 96 | DELIMITER ; 97 | 98 | -- 4. Triggered 99 | -- Create a table deleted_employees(employee_id PK, first_name, 100 | -- last_name,middle_name,job_title,deparment_id,salary) that will hold 101 | -- information about fired(deleted) employees from the employees table. 102 | -- Add a trigger to employees table that inserts the corresponding 103 | -- information in deleted_employees. 104 | 105 | CREATE TABLE deleted_employees( 106 | `employee_id` INT PRIMARY KEY AUTO_INCREMENT, 107 | `first_name` VARCHAR(20), 108 | `last_name` VARCHAR(20), 109 | `middle_name` VARCHAR(20), 110 | `job_title` VARCHAR(50), 111 | `department_id` INT, 112 | `salary` DOUBLE 113 | ); 114 | 115 | DELIMITER $$ 116 | CREATE TRIGGER tr_deleted_employees 117 | AFTER DELETE ON `employees` 118 | FOR EACH ROW 119 | BEGIN 120 | INSERT INTO `deleted_employees` 121 | (`first_name`, `last_name`, `middle_name`, 122 | `job_title`, `department_id`, `salary`) 123 | VALUES (OLD.first_name, OLD.last_name, OLD.middle_name, 124 | OLD.job_title, OLD.department_id, OLD.salary); 125 | END $$ 126 | DELIMITER ; 127 | 128 | 129 | -- Examples from presentation slides 130 | 131 | DELIMITER $$ 132 | CREATE PROCEDURE usp_select_employees_by_seniority() 133 | BEGIN 134 | SELECT * 135 | FROM `employees` AS e 136 | WHERE ROUND(DATEDIFF(NOW(), e.hire_date) / 365.25) < 15; 137 | END $$ 138 | DELIMITER ; 139 | 140 | CALL usp_select_employees_by_seniority(); 141 | 142 | DROP PROCEDURE usp_select_employees_by_seniority; 143 | 144 | -- 145 | DELIMITER $$ 146 | CREATE PROCEDURE usp_select_employees_by_seniority(min_years_at_work INT) 147 | BEGIN 148 | SELECT 149 | e.first_name, 150 | e.last_name, 151 | e.hire_date, 152 | ROUND(DATEDIFF(NOW(), e.hire_date) / 365.25) AS 'years' 153 | FROM `employees` AS e 154 | WHERE ROUND(DATEDIFF(NOW(), e.hire_date) / 365.25) > min_years_at_work 155 | ORDER BY e.hire_date; 156 | END $$ 157 | DELIMITER ; 158 | 159 | CALL usp_select_employees_by_seniority(15); 160 | 161 | DROP PROCEDURE usp_select_employees_by_seniority; 162 | 163 | -- 164 | DELIMITER $$ 165 | CREATE PROCEDURE usp_add_numbers( 166 | first_number INT, second_number INT, OUT result INT) 167 | BEGIN 168 | SET result := first_number + second_number; 169 | END $$ 170 | DELIMITER ; 171 | 172 | SET @result=0; 173 | CALL usp_add_numbers(5, 6, @result); 174 | SELECT @result as 'result'; 175 | 176 | DROP PROCEDURE usp_add_numbers; -------------------------------------------------------------------------------- /09. Exam Preparation 1/01. DDL - Table Design.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/09. Exam Preparation 1/01. DDL - Table Design.docx -------------------------------------------------------------------------------- /09. Exam Preparation 1/01. DDL - Table Design_Data Set.sql: -------------------------------------------------------------------------------- 1 | SET foreign_key_checks = 0; 2 | INSERT INTO Departments(Id, Name) 3 | VALUES(1, 'Infrastructure'), (2, 'Aged Care'), (3, 'Legal'), (4, 'Emergency'), (5, 'Roads Maintenance'), (6, 'Animals Care'), (7, 'Forestry Office'), (8, 'Property Management'), (9, 'Event Management'), (10, 'Environment'); 4 | 5 | INSERT INTO Categories(Id, 6 | Name, 7 | Department_id) 8 | VALUES(1, 'Snow Removal', 5), (2, 'Recycling', 10), (3, 'Water/Air Pollution', 10), (4, 'Streetlight', 1), (5, 'Illegal Construction', 8), (6, 'Sports Events', 9), (7, 'Homeless Elders', 2), (8, 'Disabled People', 2), (9, 'Art Events', 9), (10, 'Animal in Danger', 6), (11, 'Destroyed Home', 4), (12, 'Street animal', 6), (13, 'Music Events', 9), (14, 'Dangerous Building', 8), (15, 'Traffic Lights', 5), (16, 'Potholes', 5), (17, 'Green Areas', 7), (18, 'Dangerous Trees', 7); 9 | 10 | INSERT INTO Status(Id, 11 | Label) 12 | VALUES(1, 'waiting'), (2, 'in progress'), (3, 'completed'), (4, 'blocked'); 13 | 14 | INSERT INTO Employees(Id, 15 | First_name, 16 | Last_name, 17 | Gender, 18 | Birthdate, 19 | Department_Id) 20 | VALUES(1, 'Marlo', 'O''Malley', 'M', '1958-9-21', 1), (2, 'Nolan', 'Meneyer', 'M', '1961-4-29', 6), (3, 'Tarah', 'McWaters', 'F', '1954-5-22', 9), (4, 'Bernetta', 'Bigley', 'F', '1979-10-18', 2), (5, 'Gregory', 'Stithe', 'M', '1952-6-25', 5), (6, 'Bord', 'Hambleton', 'M', NULL, 8), (7, 'Humphrey', 'Tamblyn', 'M', '1941-3-26', 6), (8, 'Dinah', 'Zini', 'F', '1950-9-8', 10), (9, 'Eustace', 'Sharpling', 'M', '1956-10-29', 1), (10, 'Shannon', 'Partridge', 'M', '1952-2-14', 1), (11, 'Nancey', 'Heintsch', 'F', '1967-8-20', 3), (12, 'Niki', 'Stranaghan', 'M', '1969-11-26', 9), (13, 'Dick', 'Wentworth', 'M', '1983-4-29', 4), (14, 'Ives', 'McNeigh', 'M', '1952-11-15', 1), (15, 'Leonardo', 'Shopcott', 'M', '1939-1-15', 6), (16, 'Howard', 'Lovelady', 'M', '1969-6-6', 5), (17, 'Bron', 'Ledur', 'M', '1996-11-26', 10), (18, 'Adelind', 'Benns', 'F', '1935-11-23', 10), (19, 'Imogen', 'Burnup', 'F', '1952-5-8', 3), (20, 'Eldon', 'Gaze', 'M', '1947-8-24', 5), (21, 'Patsy', 'McLenahan', 'F', NULL, 10), (22, 'Jeane', 'Salisbury', 'F', '1967-9-13', 5), (23, 'Tiena', 'Ritchard', 'F', '1985-4-18', 3), (24, 'Hakim', 'Guilaem', 'M', '1963-4-9', 9), (25, 'Corny', 'Pickthall', 'M', '1979-12-18', 2), (26, 'Tam', 'Kornel', 'M', '1995-10-3', 9), (27, 'Abby', 'Brettoner', 'F', '1992-4-16', 9), (28, 'Galven', 'Moston', 'M', '1945-3-20', 5), (29, 'Stefa', 'Jakubovski', 'F', '1947-1-10', 2), (30, 'Hewet', 'Juschke', 'M', '1997-12-26', 7); 21 | 22 | INSERT INTO Users(Id, 23 | Username, 24 | Name, 25 | Password, 26 | Gender, 27 | BirthDate, 28 | Age, 29 | Email) 30 | VALUES 31 | (1, 'ealpine0', 'Erhart Alpine', 'b8eYD1a7R44', 'F', '1949-07-07', 68, 'ealpine0@squarespace.com'), 32 | (2, 'awight1', 'Anitra Wight', 'hbHhuwBSxqeo', 'F', '1943-05-31', 74, 'awight1@artisteer.com'), 33 | (3, 'fmacane2', 'Faustine MacAne', 'nhpbS3h2rfR', 'M', '1944-11-19', 73, 'fmacane2@is.gd'), 34 | (4, 'fdenrico3', 'Florette D''Enrico', '0iMw1JpVk4', 'F', '1977-10-26', 40, 'fdenrico3@va.gov'), 35 | (5, 'lrow4', 'Lindsey Row', 'neGBinke', 'F', '1934-01-16', 83, 'lrow4@netscape.com'), 36 | (6, 'dfinicj5', 'NULL', '2GDReU', 'F', '1993-05-20', 24, 'shynson5@ihg.com'), 37 | (7, 'llankham6', 'Lishe Lankham', 'ygNzd2f', 'F', '1951-11-05', 66, 'llankham6@histats.com'), 38 | (8, 'tmartensen7', 'Tawnya Martensen', 'KyFw9oA', 'M', '1980-11-21', 37, 'tmartensen7@cornell.edu'), 39 | (9, 'mgobbett8', 'Maud Gobbett', 'anv5ba2pvM', 'F', '1958-10-29', 59, 'mgobbett8@dmoz.org'), 40 | (10, 'vinglese9', 'Veronique Inglese', 'ZCJp511W', 'M', '1962-02-16', 55, 'vinglese9@g.co'), 41 | (11, 'mburdikina', 'Maggi Burdikin', 'MjXufd', 'F', '1986-04-23', 31, 'mburdikina@boston.com'), 42 | (12, 'varkwrightb', 'Vanni Arkwright', 'sWKjjlWE', 'M', '1964-02-29', 53, '6varkwrightb@ucoz.com'), 43 | (13, '5omarkwelleyc', 'Odette Markwelley', 'UfUE4pE', 'F', '1998-05-23', 19, 'omarkwelleyc@alibaba.com'), 44 | (14, 'dpennid', 'Dorene Penni', 'rIBnJ77b', 'F', '1959-09-07', 58, 'dpennid@arizona.edu'), 45 | (15, 'wkicke', 'Wileen Kick', '7bZQ3gntC', 'M', '1962-09-20', 55, 'wkicke@disqus.com'), 46 | (16, '1qiskowf', 'Quent Iskow', 'DCDiR6YTf8', 'F', '1958-12-18', 59, 'qiskowf@opensource.org'), 47 | (17, 'bkaasg', 'Brig Kaas', 'D1oonIJDX3G', 'M', '1996-07-13', 21, 'bkaasg@g.co'), 48 | (18, 'gdiaperh', 'Germaine Diaper', 'YM05Ya6Xpo7', 'F', '1939-05-26', 78, 'gdiaperh@nsw.gov.au'), 49 | (19, '1eallibertoni', 'Emlynn Alliberton', 's8XQ0d7iv', 'F', '1972-07-29', 45, 'eallibertoni@slashdot.org'), 50 | (20, 'jgreggorj', 'Jocko Greggor', 'H1J1AbJW4BEB', 'M', '1981-04-22', 36, 'jgreggorj@whitehouse.gov'); 51 | 52 | INSERT INTO Reports(Id, 53 | Category_Id, 54 | Status_Id, 55 | Open_Date, 56 | Close_Date, 57 | Description, 58 | User_Id, 59 | Employee_Id) 60 | VALUES 61 | (1, 1, 4, '2017-04-13', NULL, 'Stuck Road on Str.14', 14, 5), 62 | (2, 2, 3, '2015-09-05', '2015-09-17', '366 kg plastic for recycling.', 10, NULL), 63 | (3, 1, 2, '2015-01-03', NULL, 'Stuck Road on Str.29', 4, 22), 64 | (4, 11, 4, '2015-12-06', NULL, 'Burned facade on Str.183', 7, NULL), 65 | (5, 4, 4, '2015-11-17', NULL, 'Fallen streetlight columns on Str.40', 3, NULL), 66 | (6, 18, 1, '2015-09-07', NULL, 'Fallen Tree on the road on Str.26', 14, 30), 67 | (7, 2, 2, '2017-09-07', NULL, 'High grass in Park Riversqaure', 10, 8), 68 | (8, 18, 3, '2016-04-23', '2016-05-01', 'Fallen Tree on the road on Str.26', 11, NULL), 69 | (9, 10, 4, '2014-12-17', NULL, 'Stuck Road on Str.65', 1, 15), 70 | (10, 2, 4, '2015-08-23', NULL, '399 kg plastic for recycling.', 12, 17), 71 | (11, 4, 3, '2017-07-03', '2017-07-06', 'Fallen streetlight columns on Str.41', 19, 14), 72 | (12, 10, 3, '2016-07-20', '2016-08-13', 'Burned facade on Str.793', 7, 7), 73 | (13, 1, 2, '2016-01-26', NULL, '246 kg plastic for recycling.', 16, 20), 74 | (14, 12, 1, '2016-06-09', NULL, 'Aggressive monkey corner of Str.36 and Str.92', 20, NULL), 75 | (15, 1, 4, '2015-06-20', NULL, 'Stuck Road on Str.133', 17, NULL), 76 | (16, 6, 1, '2015-10-09', NULL, 'Stuck Road on Str.66', 18, 24), 77 | (17, 11, 4, '2015-08-26', NULL, 'Burned facade on Str.560', 14, NULL), 78 | (18, 6, 4, '2014-10-24', NULL, '86 kg plastic for recycling.', 10, 24), 79 | (19, 11, 4, '2016-01-14', NULL, '39 kg plastic for recycling.', 6, 13), 80 | (20, 16, 1, '2016-07-02', NULL, 'Gigantic crater ?n Str.48', 3, NULL), 81 | (21, 2, 4, '2015-03-31', NULL, 'High grass in Park Riversqaure', 14, 17), 82 | (22, 14, 1, '2016-05-15', NULL, 'Falling bricks on Str.17', 14, NULL), 83 | (23, 2, 3, '2017-07-24', '2017-07-27', 'Stuck Road on Str.8', 16, 18), 84 | (24, 1, 3, '2015-05-23', '2016-05-19', 'Stuck Road on Str.123', 13, 16), 85 | (25, 17, 1, '2016-01-11', NULL, '162 kg plastic for recycling.', 19, 30), 86 | (26, 10, 2, '2016-11-10', '2016-11-20', 'Parked car on green area on the sidewalk of Str.74', 20, 15), 87 | (27, 9, 2, '2014-12-17', NULL, 'Art exhibition on July 24', 8, NULL), 88 | (28, 2, 4, '2017-07-12', NULL, 'Stuck Road on Str.13', 2, 18), 89 | (29, 14, 3, '2015-09-25', '2016-10-12', 'Falling bricks on Str.38', 12, 13), 90 | (30, 3, 4, '2016-08-02', NULL, 'Extreme increase in nitrogen dioxide at Litchfield', 4, NULL), 91 | (31, 4, 4, '2017-09-12', NULL, 'Fallen streetlight columns on Str.14', 1, 1), 92 | (32, 6, 3, '2015-06-08', '2015-06-13', 'Sky Run competition on September 8', 19, 12), 93 | (33, 16, 2, '2015-11-17', NULL, 'Gigantic crater ?n Str.19', 1, NULL), 94 | (34, 2, 4, '2017-07-10', NULL, 'Glass Bottles for recycling on Str.105', 5, NULL), 95 | (35, 2, 1, '2017-02-06', NULL, 'Glass Bottles for recycling on Str.28', 5, NULL), 96 | (36, 4, 2, '2016-01-01', NULL, 'Fallen streetlight columns on Str.15', 18, NULL), 97 | (37, 5, 1, '2017-08-28', NULL, 'Glass Bottles for recycling on Str.150', 13, 17), 98 | (38, 7, 2, '2016-02-27', NULL, 'Lonely child on corner of Str.3 and Str.30', 16, NULL), 99 | (39, 9, 1, '2016-02-11', NULL, 'Glass Bottles for recycling on Str.116', 10, NULL), 100 | (40, 7, 1, '2015-11-05', NULL, 'Lonely child on corner of Str.1 and Str.19', 7, 25); 101 | SET foreign_key_checks = 1; -------------------------------------------------------------------------------- /09. Exam Preparation 1/Databases MySQL Exam - 22 Oct 2017.sql: -------------------------------------------------------------------------------- 1 | -- https://judge.softuni.bg/Contests/Practice/Index/823#0 2 | 3 | CREATE DATABASE `report_service`; 4 | 5 | USE `report_service`; 6 | 7 | -- Section 1. DDL (30 pts) 8 | -- 01. DDL - Table Design 9 | 10 | CREATE TABLE `users` ( 11 | `id` INT(11) UNSIGNED UNIQUE NOT NULL AUTO_INCREMENT PRIMARY KEY, 12 | `username` VARCHAR(30) UNIQUE, 13 | `password` VARCHAR(50) NOT NULL, 14 | `name` VARCHAR(50), 15 | `gender` VARCHAR(1), 16 | `birthdate` DATETIME, 17 | `age` INT(11) UNSIGNED, 18 | `email` VARCHAR(50) NOT NULL 19 | ); 20 | 21 | CREATE TABLE `departments` ( 22 | `id` INT(11) UNSIGNED UNIQUE NOT NULL AUTO_INCREMENT PRIMARY KEY, 23 | `name` VARCHAR(50) NOT NULL 24 | ); 25 | 26 | CREATE TABLE `employees` ( 27 | `id` INT(11) UNSIGNED UNIQUE NOT NULL AUTO_INCREMENT PRIMARY KEY, 28 | `first_name` VARCHAR(25), 29 | `last_name` VARCHAR(25), 30 | `gender` VARCHAR(1), 31 | `birthdate` DATETIME, 32 | `age` INT(11) UNSIGNED, 33 | `department_id` INT(11) UNSIGNED, 34 | CONSTRAINT `fk_users_departments` FOREIGN KEY (`department_id`) 35 | REFERENCES `departments` (`id`) 36 | ); 37 | 38 | CREATE TABLE `categories` ( 39 | `id` INT(11) UNSIGNED UNIQUE NOT NULL AUTO_INCREMENT PRIMARY KEY, 40 | `name` VARCHAR(50) NOT NULL, 41 | `department_id` INT(11) UNSIGNED, 42 | CONSTRAINT `fk_categories_departments` FOREIGN KEY (`department_id`) 43 | REFERENCES `departments` (`id`) 44 | ); 45 | 46 | CREATE TABLE `status` ( 47 | `id` INT(11) UNSIGNED UNIQUE NOT NULL AUTO_INCREMENT PRIMARY KEY, 48 | `label` VARCHAR(30) NOT NULL 49 | ); 50 | 51 | CREATE TABLE `reports` ( 52 | `id` INT(11) UNSIGNED UNIQUE NOT NULL AUTO_INCREMENT PRIMARY KEY, 53 | `category_id` INT(11) UNSIGNED, 54 | `status_id` INT(11) UNSIGNED, 55 | `open_date` DATETIME, 56 | `close_date` DATETIME, 57 | `description` VARCHAR(200), 58 | `user_id` INT(11) UNSIGNED, 59 | `employee_id` INT(11) UNSIGNED, 60 | CONSTRAINT `fk_reports_categories` FOREIGN KEY (`category_id`) 61 | REFERENCES `categories` (`id`), 62 | CONSTRAINT `fk_reports_status` FOREIGN KEY (`status_id`) 63 | REFERENCES `status` (`id`), 64 | CONSTRAINT `fk_reports_users` FOREIGN KEY (`user_id`) 65 | REFERENCES `users` (`id`), 66 | CONSTRAINT `fk_reports_employees` FOREIGN KEY (`employee_id`) 67 | REFERENCES `employees` (`id`) 68 | ); 69 | 70 | 71 | -- Section 2. DML (10 pts) 72 | -- 2. Insert 73 | 74 | INSERT INTO `employees` 75 | (`first_name`, `last_name`, `gender`, `birthdate`, `department_id`) 76 | VALUES 77 | ('Marlo', 'O''Malley', 'M', '1958-09-21', 1), 78 | ('Niki', 'Stanaghan', 'F', '1969-11-26', 4), 79 | ('Ayrton', 'Senna', 'M', '1960-03-21', 9), 80 | ('Ronnie', 'Peterson', 'M', '1944-02-14', 9), 81 | ('Giovanna', 'Amati', 'F', '1959-07-20', 5); 82 | 83 | INSERT INTO `reports` 84 | (`category_id`, `status_id`, `open_date`, `close_date`, 85 | `description`, `user_id`, `employee_id`) 86 | VALUES 87 | (1, 1, '2017-04-13', NULL, 'Stuck Road on Str.133', 6, 2), 88 | (6, 3, '2015-09-05', '2015-12-06', 'Charity trail running', 3, 5), 89 | (14, 2, '2015-09-07', NULL, 'Falling bricks on Str.58', 5, 2), 90 | (4, 3, '2017-07-03', '2017-07-06', 'Cut off streetlight on Str.11', 1, 1); 91 | 92 | 93 | -- 3. Update 94 | -- Switch all report’s status to 2 where it is currently 1 for the 4 category. 95 | 96 | UPDATE `reports` 97 | SET 98 | `status_id` = 2 99 | WHERE 100 | `status_id` = 1 AND `category_id` = 4; 101 | 102 | 103 | -- 4. Delete 104 | -- Delete all reports who have a status 4. 105 | 106 | DELETE FROM `reports` 107 | WHERE 108 | `status_id` = 4; 109 | 110 | 111 | -- Section 3. Querying (40 pts) 112 | -- You need to start with a fresh dataset, so recreate your DB and 113 | -- import the sample data again (Data_ReportService.sql). 114 | 115 | -- 5. Users by Age 116 | -- Select all usernames and age ordered by age (ascending) then by username (descending). 117 | 118 | SELECT 119 | u.username, u.age 120 | FROM 121 | `users` AS u 122 | ORDER BY u.age , u.username DESC; 123 | 124 | -- 6. Unassigned Reports 125 | -- Find all reports that don’t have an assigned employee. 126 | -- Order the results by open_date in ascending order, then by description. 127 | 128 | SELECT 129 | r.description, r.open_date 130 | FROM 131 | `reports` AS r 132 | WHERE 133 | r.employee_id IS NULL 134 | ORDER BY r.open_date, r.description; 135 | 136 | 137 | -- 7. Employees and Reports 138 | -- Select only employees who have an assigned report and show all reports of 139 | -- each found employee. Show the open date column in the format “yyyy-MM-dd”. 140 | -- Order them by employee_id (ascending) then by open_date (again ascending) 141 | -- and by report_id ascending. 142 | 143 | SELECT 144 | e.first_name, 145 | e.last_name, 146 | r.description, 147 | DATE_FORMAT(r.open_date, '%Y-%m-%d') AS 'open_date' 148 | FROM 149 | `reports` AS r 150 | JOIN 151 | `employees` AS e ON r.employee_id = e.id 152 | ORDER BY r.employee_id , r.open_date , r.id; 153 | 154 | 155 | -- 8. Most Reported Category 156 | -- Select ALL categories and order them by the number of reports per 157 | -- category in ascending order and then alphabetically by name. 158 | 159 | SELECT 160 | c.`name` AS 'category_name', COUNT(*) AS 'reports_number' 161 | FROM 162 | `categories` AS c 163 | JOIN 164 | `reports` AS r ON c.id = r.category_id 165 | GROUP BY r.category_id 166 | ORDER BY `reports_number` , c.`name`; 167 | 168 | 169 | -- 9. One Category Employees 170 | -- Select ALL categories and the number of employees in each 171 | -- category and order them alphabetically by category name. 172 | 173 | SELECT 174 | c.`name`, COUNT(e.id) AS 'employees_number' 175 | FROM 176 | `categories` AS c 177 | JOIN 178 | `employees` AS e ON c.department_id = e.department_id 179 | GROUP BY c.`name` 180 | ORDER BY c.`name`; 181 | 182 | 183 | -- 10. Birthday Report 184 | -- Select all categories in which users have submitted a report 185 | -- on their birthday. Order them by name alphabetically. 186 | -- Duplicates are not needed. 187 | 188 | SELECT DISTINCT 189 | (c.`name`) AS 'category_name' 190 | FROM 191 | `reports` AS r 192 | JOIN 193 | `users` AS u ON r.user_id = u.id 194 | JOIN 195 | `categories` AS c ON r.category_id = c.id 196 | WHERE 197 | DAY(r.open_date) = DAY(u.birthdate) 198 | AND MONTH(r.open_date) = MONTH(u.birthdate) 199 | ORDER BY `category_name`; 200 | 201 | 202 | -- 11. Users per Employee 203 | -- Select all employees and show how many unique users each of them have served to. 204 | -- Required columns: 205 | -- Employee’s name - Full name consisting of first_name and last_name and a space between them 206 | -- User’s count 207 | -- Order by users_number descending and then by name ascending. 208 | 209 | SELECT 210 | CONCAT_WS(' ', e.first_name, e.last_name) AS 'name', 211 | COUNT(DISTINCT (r.user_id)) AS 'users_count' 212 | FROM 213 | `employees` AS e 214 | LEFT OUTER JOIN 215 | `reports` AS r ON e.id = r.employee_id 216 | GROUP BY e.id 217 | ORDER BY `users_count` DESC , `name`; 218 | 219 | 220 | -- 12. Emergency Patrol 221 | -- Select all reports which satisfy all the following criteria: 222 | -- are not closed yet (they don’t have a close_date) 223 | -- the description is longer than 20 symbols and the word “str” is mentioned anywhere 224 | -- are assigned to one of the following departments: “Infrastructure”, “Emergency”, “Roads Maintenance” 225 | -- Order the results by open_date and then by Reporter’s Email and report_id ascending. 226 | 227 | SELECT 228 | r.open_date, r.description, u.email AS 'reporter_email' 229 | FROM 230 | `reports` AS r 231 | JOIN 232 | `users` AS u ON r.user_id = u.id 233 | JOIN 234 | `categories` AS c ON r.category_id = c.id 235 | JOIN 236 | `departments` AS d ON c.department_id = d.id 237 | WHERE 238 | r.close_date IS NULL 239 | AND LENGTH(r.description) > 20 240 | AND r.description LIKE '%str%' 241 | AND d.`name` IN ('Infrastructure' , 'Emergency', 'Roads Maintenance') 242 | ORDER BY r.open_date , u.email , r.id; 243 | 244 | 245 | -- 13. Numbers Coincidence 246 | -- Select all usernames which: 247 | -- starts with a digit and have reported in a category with id equal to the digit 248 | -- OR 249 | -- ends with a digit and have reported in a category with id equal to the digit 250 | -- Order them alphabetically. 251 | 252 | SELECT 253 | DISTINCT(u.`username`) 254 | FROM 255 | `reports` AS r 256 | JOIN 257 | `users` AS u ON r.user_id = u.id 258 | JOIN 259 | `categories` AS c ON r.category_id = c.id 260 | WHERE 261 | (LEFT(u.`username`, 1) REGEXP '^[0-9]') 262 | AND CAST(LEFT(u.`username`, 1) AS UNSIGNED) = c.id 263 | OR (RIGHT(u.`username`, 1) REGEXP '^[0-9]') 264 | AND CAST(RIGHT(u.`username`, 1) AS UNSIGNED) = c.id 265 | ORDER BY u.`username`; 266 | 267 | -- Another WHERE clause: 268 | SELECT DISTINCT 269 | (u.`username`) 270 | FROM 271 | `reports` AS r 272 | JOIN 273 | `users` AS u ON r.user_id = u.id 274 | JOIN 275 | `categories` AS c ON r.category_id = c.id 276 | WHERE 277 | (CAST(c.id AS CHAR (50)) = LEFT(u.username, 1)) 278 | OR (CAST(c.id AS CHAR (50)) = RIGHT(u.username, 1)) 279 | ORDER BY u.`username`; 280 | 281 | -- Simplified WHERE clause: 282 | SELECT DISTINCT 283 | (u.`username`) 284 | FROM 285 | `reports` AS r 286 | JOIN 287 | `users` AS u ON r.user_id = u.id 288 | JOIN 289 | `categories` AS c ON r.category_id = c.id 290 | WHERE 291 | c.id = LEFT(u.username, 1) 292 | OR c.id = RIGHT(u.username, 1) 293 | ORDER BY u.`username`; 294 | 295 | -- 14. Open/Closed Statistics 296 | -- Select all employees who have at least one assigned closed (have a closed_date value) 297 | -- / open report through year 2016 and their number. Reports that have been opened before 298 | -- 2016 but were closed in 2016 are counted as closed only! 299 | -- Order the results by name alphabetically. 300 | 301 | SELECT 302 | g.`name`, 303 | CONCAT_WS('/', g.`close`, g.`open`) AS 'closed_open_reports' 304 | FROM 305 | (SELECT 306 | CONCAT_WS(' ', e.first_name, e.last_name) AS 'name', 307 | COUNT(IF(YEAR(r.close_date) = 2016, 1, NULL)) AS 'close', 308 | COUNT(IF(YEAR(r.open_date) = 2016, 1, NULL)) AS 'open' 309 | FROM 310 | `reports` AS r 311 | JOIN `employees` AS e ON r.employee_id = e.id 312 | GROUP BY `name` 313 | HAVING `close` > 0 OR `open` > 0) AS g 314 | ORDER BY `name`; 315 | 316 | -- One SELECT solution 317 | SELECT 318 | CONCAT_WS(' ', e.first_name, e.last_name) AS 'name', 319 | CONCAT_WS('/', 320 | CAST(COUNT(IF(YEAR(r.close_date) = 2016, 1, NULL)) 321 | AS CHAR), 322 | CAST(COUNT(IF(YEAR(r.open_date) = 2016, 1, NULL)) 323 | AS CHAR)) AS 'closed_open_reports' 324 | FROM 325 | `reports` AS r 326 | JOIN 327 | `employees` AS e ON r.employee_id = e.id 328 | WHERE 329 | YEAR(r.close_date) = 2016 330 | OR YEAR(r.open_date) = 2016 331 | GROUP BY `name` 332 | ORDER BY `name`; 333 | 334 | 335 | -- 15. Average Closing Time 336 | -- Select all departments that have been reported in and the average time(in days) 337 | -- for closing a report for each department. If there is no information (e.g. none 338 | -- closed reports) about any department fill in the Average Duration column “no info”. 339 | -- Round the average duration to the nearest smaller integer value. 340 | -- Order them by department name. 341 | 342 | 343 | SELECT 344 | d.name AS 'department_name', 345 | IFNULL(FLOOR(AVG(DATEDIFF(r.close_date, r.open_date))), 346 | 'no info') AS 'average_duration' 347 | FROM 348 | `reports` AS r 349 | JOIN 350 | `categories` AS c ON c.id = r.category_id 351 | JOIN 352 | `departments` AS d ON d.id = c.department_id 353 | GROUP BY d.id 354 | ORDER BY d.name; 355 | 356 | -- Another SELECT: 357 | SELECT 358 | d.name AS 'department_name', 359 | IF(COUNT(r.close_date) = 0, 360 | 'no info', 361 | CAST(FLOOR(AVG(DATEDIFF(r.close_date, r.open_date))) 362 | AS CHAR)) AS 'average_duration' 363 | FROM 364 | `reports` AS r 365 | JOIN 366 | `categories` AS c ON c.id = r.category_id 367 | JOIN 368 | `departments` AS d ON d.id = c.department_id 369 | GROUP BY d.id 370 | ORDER BY d.name; 371 | 372 | -- 16. Most Reported Category 373 | -- Select all departments with their categories where users have 374 | -- submitted a report. Show the distribution of reports among the 375 | -- categories of each department in percentages without decimal part. 376 | -- Order them by department name, then by category name and then 377 | -- by percentage (all in ascending order). 378 | 379 | SELECT 380 | d.name AS 'department_name', 381 | c.name AS 'category_name', 382 | ROUND((COUNT(r.id) / (SELECT 383 | COUNT(r1.id) 384 | FROM 385 | `reports` AS r1 386 | JOIN 387 | `categories` AS c1 ON c1.id = r1.category_id 388 | JOIN 389 | `departments` AS d1 ON d1.id = c1.department_id 390 | WHERE 391 | d1.id = d.id 392 | GROUP BY d1.id)) * 100, 393 | 0) AS 'percentage' 394 | FROM 395 | `reports` AS r 396 | JOIN 397 | `categories` AS c ON c.id = r.category_id 398 | JOIN 399 | `departments` AS d ON d.id = c.department_id 400 | GROUP BY d.id , c.id 401 | ORDER BY d.name , c.name , `percentage`; 402 | 403 | 404 | -- Section 4. Programmability (20 pts) 405 | 406 | -- 17. Get Reports 407 | -- Create a user defined function with the name 408 | -- udf_get_reports_count(employee_id INT, status_id INT) 409 | -- that receives an employee’s Id and a status Id returns the 410 | -- sum of the reports he is assigned to with the given status. 411 | 412 | -- Example usage: 413 | SELECT 414 | id, 415 | first_name, 416 | last_name, 417 | UDF_GET_REPORTS_COUNT(id, 2) AS reports_count 418 | FROM 419 | employees AS e 420 | ORDER BY e.id; 421 | 422 | 423 | CREATE FUNCTION udf_get_reports_count(employee_id INT, status_id INT) 424 | RETURNS INT 425 | RETURN ( 426 | SELECT COUNT(r.id) 427 | FROM `reports` AS r 428 | WHERE r.employee_id = employee_id 429 | AND r.status_id = status_id); 430 | 431 | 432 | -- 18. Assign Employee 433 | -- Create a user defined stored procedure with the name 434 | -- usp_assign_employee_to_report(employee_id INT, report_id INT) 435 | -- that receives an employee’s Id and a report’s Id and assigns 436 | -- the employee to the report only if the department of the employee 437 | -- and the department of the report’s category are the same. 438 | -- If the assigning is not successful rollback any changes and throw 439 | -- an exception with message: 440 | -- “Employee doesn't belong to the appropriate department!” 441 | 442 | -- Example usage: 443 | CALL usp_assign_employee_to_report(30, 1); -- Response: Employee doesn't belong to the appropriate department! 444 | 445 | CALL usp_assign_employee_to_report(17, 2); 446 | SELECT employee_id FROM reports WHERE id = 2; -- Response: 17 447 | 448 | DELIMITER $$ 449 | CREATE PROCEDURE usp_assign_employee_to_report(employee_id INT, report_id INT) 450 | BEGIN 451 | DECLARE employee_department_id INT DEFAULT (SELECT e.department_id FROM `employees` AS e WHERE e.id = employee_id); 452 | DECLARE report_category_id INT DEFAULT (SELECT r.category_id FROM `reports` AS r WHERE r.id = report_id); 453 | DECLARE category_department_id INT DEFAULT (SELECT c.department_id FROM `categories` AS c WHERE c.id = report_category_id); 454 | 455 | START TRANSACTION; 456 | IF(employee_department_id != category_department_id) THEN 457 | SIGNAL SQLSTATE '45000' 458 | SET MESSAGE_TEXT = 'Employee doesn\'t belong to the appropriate department!'; 459 | ROLLBACK; 460 | ELSE 461 | UPDATE `reports` AS r 462 | SET r.employee_id = employee_id 463 | WHERE r.id = report_id; 464 | COMMIT; 465 | END IF; 466 | END $$ 467 | DELIMITER ; 468 | 469 | 470 | -- 19. Close Reports 471 | -- Create a trigger which changes the status_id to “completed” 472 | -- of each report after a close_date is entered for the report. 473 | -- Example usage: 474 | 475 | UPDATE reports 476 | SET 477 | close_date = NOW() 478 | WHERE 479 | employee_id = 1; 480 | 481 | -- Expected Response: 2 row(s) affected 482 | 483 | DELIMITER $$ 484 | CREATE TRIGGER `tr_report_closed` 485 | BEFORE UPDATE ON `reports` 486 | FOR EACH ROW 487 | BEGIN 488 | IF (ISNULL(OLD.close_date) <> ISNULL(NEW.close_date)) THEN 489 | SET NEW.status_id = 3; 490 | END IF; 491 | END $$ 492 | DELIMITER ; 493 | 494 | 495 | -- Section 5. Bonus (10 pts) 496 | -- 20. Categories Revision 497 | -- Select all categories which have reports with status “waiting” or 498 | -- “in progress” and show their total number in the column “Reports Number”. 499 | -- In the third column fill the main status type of reports for the 500 | -- category (e.g. 2 reports with status “waiting” and 3 reports with 501 | -- status “in progress” result in value “in progress”). 502 | -- If they are equal just fill in “equal”. 503 | /* Example: 504 | category_name reports_number main_status 505 | Animal in Danger 1 in progress 506 | Art Events 2 equal 507 | Dangerous Building 1 waiting 508 | … … … */ 509 | 510 | SELECT 511 | c.name AS 'category_name', 512 | COUNT(r.id) AS 'reports_number', 513 | IF(COUNT(IF(r.status_id = 1, 1, NULL)) = COUNT(IF(r.status_id = 2, 1, NULL)), 514 | 'equal', 515 | IF(COUNT(IF(r.status_id = 1, 1, NULL)) > COUNT(IF(r.status_id = 2, 1, NULL)), 516 | 'waiting', 517 | 'in progress')) AS 'main_status' 518 | FROM 519 | `categories` AS c 520 | JOIN 521 | `reports` AS r ON c.id = r.category_id 522 | WHERE 523 | r.status_id IN (1 , 2) 524 | GROUP BY c.id 525 | ORDER BY c.name; -------------------------------------------------------------------------------- /10. Exam Preparation 2/00. Login_Tables.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE logged_in_users ( 2 | id INT, 3 | username VARCHAR(30) NOT NULL UNIQUE, 4 | password VARCHAR(30) NOT NULL, 5 | email VARCHAR(50), 6 | CONSTRAINT pk_logged_in_users PRIMARY KEY (id) 7 | ); 8 | 9 | CREATE TABLE evaluated_submissions ( 10 | id INT AUTO_INCREMENT, 11 | problem VARCHAR(100) NOT NULL, 12 | user VARCHAR(30) NOT NULL, 13 | result INT NOT NULL, 14 | CONSTRAINT pk_evaluated_submissions PRIMARY KEY (id) 15 | ); -------------------------------------------------------------------------------- /10. Exam Preparation 2/01. Table Design.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/10. Exam Preparation 2/01. Table Design.docx -------------------------------------------------------------------------------- /10. Exam Preparation 2/01. Table Design_Data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO users (id, username, password, email) 2 | VALUES 3 | (1,'density','asteriks19','default@gmail.com'), 4 | (2,'arien','blazeit','arienneir@yahoo.co.uk'), 5 | (3,'booster','karuusel','booster@abv.bg'), 6 | (4,'query','ex-deus132','ivan@abv.bg'), 7 | (5,'andrew','karuusel','andrew@gmail.com'), 8 | (6,'kinoa','microsecondislove','nokia@gmail.com'), 9 | (7, 'QuandoImmersia', 'breadfish', 'denisbig@yahoo.com'), 10 | (8, 'Miracle', 'deniedvelocity', 'miracle@outlook.com'), 11 | (9, 'Syndaxo', 'ytrewq', 'syndaxo@gmail.com'), 12 | (10, 'ICanHazDonuts', 'donuts4l1f3', 'peter@outlook.com'), 13 | (11, 'Mephisto', 'thedevilincoat', 'lucy@gmail.com'), 14 | (12, 'Emir', 'mirandaismylove', 'rime@abv.bg'), 15 | (13, 'Ivan', 'putin4king', 'suka@wocsom.ru'), 16 | (14, 'Tiffany', 'chalgamadafaka', 'geri@nikol.bg'), 17 | (15, 'Oleg', 'putin4king', 'blyat@wocsom.ru'), 18 | (16, 'Gruesome', 'asteriks19', 'denial@gmail.com'), 19 | (17, 'Billy', '2good4you', 'billmurry@gmail.com'), 20 | (18, 'DaRighteous1', 'tonimotori', 'toniatanasoff@gmail.com'), 21 | (19, 'Syncy', 'SymmetryIsTheNewChaos', 'SallyIsacc@yahoo.co.uk'), 22 | (20, 'Reine', 'whatisthemeaningoflie', 'reine@gmail.com'), 23 | (21, 'SecretAgent', 'fbi@gmail.com', 'boundary@sofiamemes.abv.bg'), 24 | (22, 'micro', 'breadfish', 'micro@gmail.com'), 25 | (23, 'Mellanie', 'babyyouaremine', 'mellanie@yahoo.co.uk'), 26 | (24, 'A4Tech', 'mousespls', 'damian@abv.bg'), 27 | (25, 'JohnWick', 'touchmypuppyandyoudie', 'johnny@gmail.com'), 28 | (26, 'SeriousSam', 'putin4king', 'samuel@wocsom.ru'), 29 | (27, 'doge', 'doge', 'doge@doge.doge'), 30 | (28, 'cate', 'cate', 'cate@cate.cate'), 31 | (29, 'BabyYouAreMine', 'Blasphemy', 'munich@gmail.com'), 32 | (30, 'Antena', 'seismicity', 'anderson@gmail.com'); 33 | 34 | INSERT INTO categories (id, name, parent_id) 35 | VALUES 36 | (1, 'JavaScript Development', NULL), 37 | (2, 'C# Development', NULL), 38 | (3, 'JavaScript Basics', 1), 39 | (4, 'JavaScript Advanced', 1), 40 | (5, 'Java Development', NULL), 41 | (6, 'C# Fundamentals', 2), 42 | (7, 'Java DB Fundamentals', 5), 43 | (8, 'Java DB Basics', 7), 44 | (9, 'C# OOP Basics', 6), 45 | (10, 'Java DB Advanced', 7), 46 | (11, 'JavaScript Applications', 1), 47 | (12, 'C# OOP Advanced', 6), 48 | (13, 'Java Fundamentals', 5), 49 | (14, 'PHP Development', NULL), 50 | (15, 'C# Advanced', 6), 51 | (16, 'PHP Fundamentals', 14), 52 | (17, 'PHP Web', 14), 53 | (18, 'JavaScript Web', 1), 54 | (19, 'C# DB Fundamentals', 2), 55 | (20, 'C# Web', 2); 56 | 57 | INSERT INTO contests (id, name, category_id) 58 | VALUES 59 | (1, 'JS Exercises', 15), 60 | (2, 'Some Exam', 4), 61 | (3, 'Contest Number 9', 10), 62 | (4, 'Mambo Number 5', 4), 63 | (5, 'C# OOP Exercises', 12), 64 | (6, 'JS Lab', 3), 65 | (7, 'JS Lab 2', 3), 66 | (8, 'What is This', 10), 67 | (9, 'I dunno', 15), 68 | (10, 'Chicken Nuggets', 12), 69 | (11, 'Algorithms Exam', 11), 70 | (12, 'Exam That is Hard', 13), 71 | (13, 'Test Contest', 9), 72 | (14, 'Hello Contest World', 3), 73 | (15, 'MySQL Exam 24-Jun-2017', 8), 74 | (16, 'This will be fun', 15), 75 | (17, 'Oh Im sure', 11), 76 | (18, 'I dont know what to write anymore', 4), 77 | (19, 'Sample Contest', 8), 78 | (20, 'Exams Are Hard', 9), 79 | (21, 'Making a Dataset is even Harder', 8), 80 | (22, 'When you are comming up with tha data', 3), 81 | (23, 'Yourself', 12), 82 | (24, 'I am done', 10), 83 | (25, 'Okey just a few more', 10), 84 | (26, 'Exam Contest 24-June-3017', 13), 85 | (27, 'Is it the end yet?', 3), 86 | (28, 'Exam 10-Jul-2017', 9), 87 | (29, 'Bam Bam', 4), 88 | (30, 'Khaalesi Dies', 13); 89 | 90 | INSERT INTO problems (id, name, points, tests, contest_id) 91 | VALUES 92 | (1, 'NeedForSpeed', 100, 5, 5), 93 | (2, 'Matrix Shuffle', 25, 10, 13), 94 | (3, 'Watermelon', 150, 7, 24), 95 | (4, 'Vegetable Ninja', 49, 8, 30), 96 | (5, 'Largest Rectangle', 200, 99, 9), 97 | (6, 'Airport Management System', 30, 5, 16), 98 | (7, 'Users In Countries', 350, 0, 21), 99 | (8, 'House', 400, 20, 29), 100 | (9, 'Monsters', 1000, 25, 17), 101 | (10, 'Mass Effect', 500, 10, 4), 102 | (11, 'Mass Defect', 300, 10, 11), 103 | (12, 'Lambda Core', 100, 1, 6), 104 | (13, 'Restaurant', 200, 2, 10), 105 | (14, 'Weekday Madness', 150, 3, 5), 106 | (15, 'Usernames', 10, 10, 3), 107 | (16, 'Default Value', 5, 5, 2), 108 | (17, 'Dict-Ref', 10, 0, 24), 109 | (18, 'Cubic Artillery', 25, 20, 25), 110 | (19, 'Royalism', 30, 35, 12), 111 | (20, 'Second Nature', 100, 4, 16), 112 | (21, 'H.E.L.L.', 400, 1, 21), 113 | (22, 'Emergency', 50, 50, 22), 114 | (23, 'Dict-Ref Advanced', 100, 20, 13), 115 | (24, 'Phone', 40, 25, 25), 116 | (25, 'Winecraft', 80, 99, 4), 117 | (26, 'Sound Of Silence', 20, 10, 30), 118 | (27, 'Blasphemy', 30, 25, 29), 119 | (28, 'Jeremy', 10, 10, 30), 120 | (29, 'Football', 5, 25, 1), 121 | (30, 'BitsofBits', 2, 30, 2), 122 | (31, 'NumbersToHex', 100, 29, 18), 123 | (32, 'Binary Search', 1000, 10, 1), 124 | (33, 'Designed To Crash', 450, 15, 7), 125 | (34, 'Bugs', 200, 9, 2), 126 | (35, 'Hornet Assault', 30, 10, 19), 127 | (36, 'Cubic\'s Rube', 100, 0, 3), 128 | (37, 'Major Payne', 25, 99, 2), 129 | (38, 'Borrowed Time', 300, 7, 7), 130 | (39, 'Bear Wear', 25, 6, 7), 131 | (40, 'Merry\'s games', 400, 10, 7), 132 | (41, 'Roli The Coder', 50, 25, 30), 133 | (42, 'Something', 200, 30, 13), 134 | (43, 'Test Problem', 10, 99, 14), 135 | (44, 'Hornet Armada', 200, 45, 29), 136 | (45, 'Royal NonStop', 30, 9, 27), 137 | (46, 'Sanity\'s Eclipse', 400, 5, 3), 138 | (47, 'Indestructible', 50, 1, 14), 139 | (48, 'Word Boundary', 100, 1, 19), 140 | (49, 'Sentence Split', 1000, 2, 18), 141 | (50, 'Closed Judge System', 10000, 100, 30); 142 | 143 | INSERT INTO submissions (id, passed_tests, problem_id, user_id) 144 | VALUES 145 | (1, 2, 22, 7), 146 | (2, 13, 32, 22), 147 | (3, 0, 24, 25), 148 | (4, 19, 46, 2), 149 | (5, 10, 17, 12), 150 | (6, 10, 21, 8), 151 | (7, 21, 48, 17), 152 | (8, 7, 13, 2), 153 | (9, 0, 20, 26), 154 | (10, 19, 8, 21), 155 | (11, 19, 7, 25), 156 | (12, 9, 19, 22), 157 | (13, 19, 1, 23), 158 | (14, 20, 13, 17), 159 | (15, 21, 40, 29), 160 | (16, 10, 47, 10), 161 | (17, 6, 45, 16), 162 | (18, 9, 44, 17), 163 | (19, 10, 11, 5), 164 | (20, 0, 4, 7), 165 | (21, 2, 44, 9), 166 | (22, 91, 43, 23), 167 | (23, 20, 48, 20), 168 | (24, 10, 20, 15), 169 | (25, 22, 34, 1), 170 | (26, 7, 22, 3), 171 | (27, 15, 22, 16), 172 | (28, 16, 12, 5), 173 | (29, 24, 12, 7), 174 | (30, 14, 7, 17), 175 | (31, 0, 46, 16), 176 | (32, 0, 19, 8), 177 | (33, 14, 47, 5), 178 | (34, 99, 5, 12), 179 | (35, 14, 6, 16), 180 | (36, 10, 44, 3), 181 | (37, 25, 36, 5), 182 | (38, 15, 39, 10), 183 | (39, 15, 3, 27), 184 | (40, 9, 26, 29), 185 | (41, 13, 40, 3), 186 | (42, 7, 24, 28), 187 | (43, 5, 15, 22), 188 | (44, 66, 25, 27), 189 | (45, 9, 8, 27), 190 | (46, 19, 3, 27), 191 | (47, 23, 17, 21), 192 | (48, 26, 42, 7), 193 | (49, 0, 37, 20), 194 | (50, 22, 41, 16), 195 | (51, 11, 32, 3), 196 | (52, 100, 50, 30), 197 | (53, 13, 29, 5), 198 | (54, 7, 19, 3), 199 | (55, 13, 4, 14), 200 | (56, 21, 8, 14), 201 | (57, 82, 43, 13), 202 | (58, 12, 15, 28), 203 | (59, 11, 20, 15), 204 | (60, 19, 32, 9), 205 | (61, 5, 18, 28), 206 | (62, 13, 41, 6), 207 | (63, 0, 21, 27), 208 | (64, 18, 17, 16), 209 | (65, 16, 15, 22), 210 | (66, 11, 8, 14), 211 | (67, 97, 25, 14), 212 | (68, 7, 4, 25), 213 | (69, 12, 40, 18), 214 | (70, 16, 46, 3), 215 | (71, 17, 26, 7), 216 | (72, 0, 36, 7), 217 | (73, 13, 31, 6), 218 | (74, 11, 3, 26), 219 | (75, 0, 6, 7), 220 | (76, 17, 49, 5), 221 | (77, 23, 11, 19), 222 | (78, 9, 7, 24), 223 | (79, 16, 20, 26), 224 | (80, 9, 41, 12), 225 | (81, 6, 10, 29), 226 | (82, 11, 47, 10), 227 | (83, 9, 22, 10), 228 | (84, 4, 17, 25), 229 | (85, 14, 47, 12), 230 | (86, 16, 26, 28), 231 | (87, 14, 6, 24), 232 | (88, 0, 29, 20), 233 | (89, 87, 25, 12), 234 | (90, 17, 16, 12), 235 | (91, 11, 40, 23), 236 | (92, 3, 42, 26), 237 | (93, 9, 8, 7), 238 | (94, 8, 27, 5), 239 | (95, 20, 44, 4), 240 | (96, 16, 10, 12), 241 | (97, 22, 44, 27), 242 | (98, 18, 34, 18), 243 | (99, 0, 31, 9), 244 | (100, 10, 22, 18); 245 | 246 | INSERT INTO users_contests (user_id, contest_id) 247 | VALUES 248 | (22, 10), 249 | (8, 21), 250 | (12, 20), 251 | (20, 6), 252 | (26, 1), 253 | (15, 21), 254 | (14, 8), 255 | (26, 10), 256 | (19, 23), 257 | (29, 13), 258 | (20, 24), 259 | (29, 11), 260 | (27, 26), 261 | (25, 8), 262 | (5, 1), 263 | (29, 6), 264 | (4, 25), 265 | (21, 8), 266 | (15, 15), 267 | (17, 18), 268 | (13, 24), 269 | (3, 22), 270 | (15, 10), 271 | (7, 2), 272 | (9, 4), 273 | (20, 10), 274 | (3, 19), 275 | (14, 28), 276 | (12, 27), 277 | (25, 17), 278 | (25, 13), 279 | (2, 25), 280 | (2, 10), 281 | (17, 20), 282 | (17, 19), 283 | (26, 4), 284 | (6, 12), 285 | (30, 26), 286 | (22, 8), 287 | (27, 17), 288 | (29, 1), 289 | (12, 19), 290 | (3, 16), 291 | (12, 24), 292 | (27, 18), 293 | (21, 1), 294 | (23, 1), 295 | (23, 9), 296 | (20, 5), 297 | (24, 17), 298 | (16, 21), 299 | (9, 17), 300 | (5, 22), 301 | (20, 18), 302 | (6, 4), 303 | (1, 8), 304 | (28, 2), 305 | (15, 1), 306 | (13, 14), 307 | (9, 24), 308 | (23, 8), 309 | (13, 6), 310 | (19, 30), 311 | (4, 13), 312 | (19, 22), 313 | (24, 3), 314 | (8, 8), 315 | (23, 26), 316 | (15, 12), 317 | (26, 24), 318 | (18, 23), 319 | (18, 13), 320 | (3, 21), 321 | (16, 22), 322 | (27, 6), 323 | (28, 22), 324 | (9, 23), 325 | (29, 2), 326 | (4, 30), 327 | (3, 20), 328 | (14, 23), 329 | (16, 9), 330 | (15, 26), 331 | (24, 7), 332 | (29, 26), 333 | (6, 15), 334 | (6, 30), 335 | (20, 30), 336 | (3, 28), 337 | (14, 13), 338 | (17, 13), 339 | (25, 2), 340 | (24, 16), 341 | (10, 22), 342 | (23, 16), 343 | (10, 7), 344 | (10, 25), 345 | (7, 10), 346 | (29, 8), 347 | (27, 10); 348 | -------------------------------------------------------------------------------- /10. Exam Preparation 2/Databases MySQL Exam - 24 Jun 2017.sql: -------------------------------------------------------------------------------- 1 | -- https://judge.softuni.bg/Contests/Practice/Index/671#0 2 | 3 | CREATE DATABASE `closed_judge_system`; 4 | 5 | USE `closed_judge_system`; 6 | 7 | 8 | -- Section 1: Data Definition Language (DDL) – 40 pts 9 | 10 | CREATE TABLE `users` ( 11 | `id` INT PRIMARY KEY, 12 | `username` VARCHAR(30) UNIQUE NOT NULL, 13 | `password` VARCHAR(30) NOT NULL, 14 | `email` VARCHAR(50) 15 | ); 16 | 17 | CREATE TABLE `categories` ( 18 | `id` INT PRIMARY KEY, 19 | `name` VARCHAR(50) NOT NULL, 20 | `parent_id` INT, 21 | CONSTRAINT `fk_categories_parent_id` FOREIGN KEY (`parent_id`) 22 | REFERENCES `categories` (`id`) 23 | ); 24 | 25 | CREATE TABLE `contests` ( 26 | `id` INT PRIMARY KEY, 27 | `name` VARCHAR(50) NOT NULL, 28 | `category_id` INT, 29 | CONSTRAINT `fk_contests_categories` FOREIGN KEY (`category_id`) 30 | REFERENCES `categories` (`id`) 31 | ); 32 | 33 | CREATE TABLE `problems` ( 34 | `id` INT PRIMARY KEY, 35 | `name` VARCHAR(100) NOT NULL, 36 | `points` INT NOT NULL, 37 | `tests` INT DEFAULT 0, 38 | `contest_id` INT, 39 | CONSTRAINT `fk_problems_contests` FOREIGN KEY (`contest_id`) 40 | REFERENCES `contests` (`id`) 41 | ); 42 | 43 | CREATE TABLE `submissions` ( 44 | `id` INT PRIMARY KEY AUTO_INCREMENT, 45 | `passed_tests` INT NOT NULL, 46 | `problem_id` INT, 47 | `user_id` INT, 48 | CONSTRAINT `fk_submissions_problems` FOREIGN KEY (`problem_id`) 49 | REFERENCES `problems` (`id`), 50 | CONSTRAINT `fk_submissions_users` FOREIGN KEY (`user_id`) 51 | REFERENCES `users` (`id`) 52 | ); 53 | 54 | CREATE TABLE `users_contests` ( 55 | `user_id` INT NOT NULL, 56 | `contest_id` INT NOT NULL, 57 | CONSTRAINT `pk_users_contests` PRIMARY KEY (`user_id` , `contest_id`), 58 | CONSTRAINT `fk_users_contests_users` FOREIGN KEY (`user_id`) 59 | REFERENCES `users` (`id`), 60 | CONSTRAINT `fk_users_contests_contests` FOREIGN KEY (`contest_id`) 61 | REFERENCES `contests` (`id`) 62 | ); 63 | 64 | 65 | -- Section 2: Data Manipulation Language (DML) – 30 pts 66 | 67 | -- Allow unsafe operations 68 | SET SQL_SAFE_UPDATES = 0; 69 | SET FOREIGN_KEY_CHECKS = 0; 70 | 71 | -- 02. Data Insertion 72 | -- You will have to INSERT records of data into the submissions table, based 73 | -- on the problems table. For problem with id between 1 and 10, insert data in 74 | -- the submissions table with the following values: 75 | -- * passed_tests – POWER the length of the name of the problem by 3 and take the 76 | -- SQUARE ROOT of it. SUBTRACT from the resulting value the LENGTH of the problem’s name. 77 | -- ROUND the resulting value UP. 78 | -- * problem_id – the problem’s id. 79 | -- * user_id – MULTIPLY the id of the problem by 3 and DIVIDE it by 2. 80 | -- ROUND the resulting value UP. 81 | 82 | INSERT INTO `submissions` 83 | (`passed_tests`, `problem_id`, `user_id`) 84 | SELECT 85 | CEIL(SQRT(POW(LENGTH(p.name), 3)) - LENGTH(p.name)), 86 | p.id, 87 | CEIL(p.id * 3 / 2) 88 | FROM `problems` AS p 89 | WHERE p.id BETWEEN 1 AND 10; 90 | 91 | 92 | -- 03. Data Update 93 | -- UPDATE all problems which have tests equal to 0. 94 | -- DIVIDE the problem’s id by 3 and take the REMAINDER: 95 | -- If the remainder is 0 set the column tests to the LENGTH 96 | -- of the problem’s contest’s category’s name. 97 | -- If the remainder is 1 set the column tests to the SUM 98 | -- of the ids of the problem’s submissions. 99 | -- If the remainder is 2 set the column tests to the LENGTH 100 | -- of the problem’s contest’s name. 101 | 102 | UPDATE `problems` AS p 103 | JOIN 104 | `contests` AS c ON c.id = p.contest_id 105 | JOIN 106 | `categories` AS cat ON cat.id = c.category_id 107 | SET 108 | p.tests = CASE (p.id % 3) 109 | WHEN 0 THEN LENGTH(cat.name) 110 | WHEN 1 THEN (SELECT SUM(s.id) FROM `submissions` AS s WHERE s.problem_id = p.id) 111 | WHEN 2 THEN CHAR_LENGTH(c.name) 112 | END 113 | WHERE p.tests = 0; 114 | 115 | 116 | -- 04. Data Deletion 117 | -- DELETE all users which do NOT participate in any contest. 118 | 119 | DELETE u FROM `users` AS u 120 | LEFT JOIN 121 | `users_contests` AS uc ON uc.user_id = u.id 122 | WHERE 123 | uc.user_id IS NULL; 124 | 125 | 126 | -- Disallow unsafe operations 127 | SET SQL_SAFE_UPDATES = 1; 128 | SET FOREIGN_KEY_CHECKS = 1; 129 | 130 | -- Section 3: Querying – 100 pts 131 | 132 | -- 05. Users 133 | -- Extract from the database, all of the users. 134 | -- ORDER the results ascending by user id. 135 | -- Required Columns: id (users), username, email 136 | 137 | SELECT 138 | u.id, u.username, u.email 139 | FROM 140 | `users` AS u 141 | ORDER BY u.id; 142 | 143 | 144 | -- 06. Root Categories 145 | -- Extract from the database, all root categories. 146 | -- A root category is a category which has NO parent. 147 | -- ORDER the results ascending by category id. 148 | -- Required Columns: id (categories), name (categories) 149 | 150 | SELECT 151 | c.id, c.name 152 | FROM 153 | `categories` AS c 154 | WHERE 155 | ISNULL(c.parent_id) 156 | ORDER BY c.id; 157 | 158 | 159 | -- 07. Well Tested Problems 160 | -- Extract from the database, all problems, which have MORE tests 161 | -- THAN points, and their name consists of two words. 162 | -- The two words will always be separated by a single space. 163 | -- ORDER the results descending by problem id. 164 | -- Required Columns: id (problems), name (problems), tests 165 | 166 | SELECT 167 | p.id, p.name, p.tests 168 | FROM 169 | `problems` AS p 170 | WHERE 171 | p.tests > p.points 172 | AND (LENGTH(p.name) - LENGTH(REPLACE(p.name, ' ', ''))) = 1 173 | -- AND p.name LIKE '% %' 174 | -- AND p.name REGEXP '^.+ .+$' 175 | ORDER BY p.id DESC; 176 | 177 | 178 | -- 08. Full Path Problems 179 | -- Extract from the database, all problems and the full path to them. 180 | -- The full path is the concatenation of the category’s name, 181 | -- contest’s name and problem’s name in the following format: 182 | -- {category.name} – {contest.name} – {problem.name} 183 | -- You will have to take the contest in which the problem is and 184 | -- the category in which the contest is. 185 | -- ORDER the results ascending by problem id. 186 | -- Required Columns: id (problems), full_path 187 | 188 | SELECT 189 | p.id, CONCAT_WS(' - ', cat.name, c.name, p.name) 190 | FROM 191 | `problems` AS p 192 | JOIN 193 | `contests` AS c ON c.id = p.contest_id 194 | JOIN 195 | `categories` AS cat ON cat.id = c.category_id 196 | ORDER BY p.id; 197 | 198 | 199 | -- 09. Leaf Categories 200 | -- Extract from the database, all leaf categories. 201 | -- A leaf category is a category which has NO children. 202 | -- In other words, there is no category which has the corresponding category as its parent. 203 | -- ORDER the results in alphabetically by category name, and ascending by category id. 204 | -- Required Columns: id (categories), name (categories) 205 | 206 | SELECT 207 | c.id, c.name 208 | FROM 209 | `categories` AS c 210 | LEFT JOIN 211 | `categories` AS c2 ON c.id = c2.parent_id 212 | WHERE 213 | c2.id IS NULL 214 | ORDER BY c.name, c.id; 215 | 216 | 217 | -- 10. Mainstream Passwords 218 | -- Extract from the database, all users, which have exactly the SAME password as another user. 219 | -- ORDER the results alphabetically by username, and ascending by user id. 220 | -- Required Columns: id (users), username, password 221 | 222 | SELECT DISTINCT 223 | (u.id), u.username, u.password 224 | FROM 225 | `users` AS u 226 | JOIN 227 | `users` AS u2 ON u.password = u2.password 228 | WHERE 229 | u.id != u2.id 230 | ORDER BY u.username , u.id; 231 | 232 | -- Solution with nested SELECT 233 | SELECT DISTINCT 234 | (u.id), u.username, u.password 235 | FROM 236 | `users` AS u 237 | WHERE 238 | u.password IN (SELECT 239 | u1.password 240 | FROM 241 | `users` AS u1 242 | WHERE 243 | u.id <> u1.id) 244 | ORDER BY u.username , u.id; 245 | 246 | -- 11. Most Participated Contests 247 | -- Extract from the database, the top 5 contests in terms of count of their contestants. 248 | -- ORDER the result ascending by count of contestants, and ascending by contest id. 249 | -- Required Columns: id (contests), name (contests), contestants 250 | 251 | SELECT 252 | * 253 | FROM 254 | (SELECT 255 | c.id, c.name, COUNT(uc.contest_id) AS 'contestants' 256 | FROM 257 | `contests` AS c 258 | LEFT JOIN `users_contests` AS uc ON uc.contest_id = c.id 259 | GROUP BY uc.contest_id 260 | ORDER BY `contestants` DESC , c.id DESC 261 | LIMIT 5) AS l 262 | ORDER BY l.contestants , l.id; 263 | 264 | 265 | -- 12. Most Valuable Person 266 | -- Extract from the database, all submissions of the user that 267 | -- participates in the most contests. 268 | -- For each submission (if there are any) extract the problem’s name. 269 | -- Concatenate passed_tests from the submission and tests from the 270 | -- problem in the following format: passed_tests / tests as result. 271 | -- ORDER the results descending by submission id. 272 | -- Required Columns: id (submissions), username (users), name (problems), result 273 | 274 | SELECT 275 | s.id, 276 | u.username, 277 | p.name, 278 | CONCAT_WS(' / ', s.passed_tests, p.tests) 279 | FROM 280 | `submissions` AS s 281 | JOIN 282 | `problems` AS p ON s.problem_id = p.id 283 | JOIN 284 | `users` AS u ON u.id = s.user_id 285 | WHERE 286 | u.id = (SELECT 287 | uc.user_id 288 | FROM 289 | `users_contests` AS uc 290 | GROUP BY uc.user_id 291 | ORDER BY COUNT(uc.contest_id) DESC 292 | LIMIT 1) 293 | ORDER BY s.id DESC; 294 | 295 | -- Optimised solution 296 | SELECT 297 | s.id, 298 | u.username, 299 | p.name, 300 | CONCAT_WS(' / ', s.passed_tests, p.tests) 301 | FROM 302 | (SELECT 303 | uc.user_id 304 | FROM 305 | `users_contests` AS uc 306 | GROUP BY uc.user_id 307 | ORDER BY COUNT(uc.contest_id) DESC 308 | LIMIT 1) AS m 309 | JOIN 310 | `submissions` AS s ON s.user_id = m.user_id 311 | JOIN 312 | `problems` AS p ON s.problem_id = p.id 313 | JOIN 314 | `users` AS u ON u.id = s.user_id 315 | ORDER BY s.id DESC; 316 | 317 | -- 13. Contests Maximum Points 318 | -- Extract from the database, all contests. For each contest, extract the 319 | -- maximum possible points (sum of all points of its problems IF THERE ARE ANY). 320 | -- ORDER the results descending by maximum possible points, and ascending by contest id. 321 | -- Required Columns: id (contests), name (contests), maximum_points 322 | 323 | SELECT 324 | c.id, c.name, SUM(p.points) AS 'maximum_points' 325 | FROM 326 | `contests` AS c 327 | JOIN 328 | `problems` AS p ON c.id = p.contest_id 329 | GROUP BY c.id 330 | ORDER BY `maximum_points` DESC , c.id; 331 | 332 | 333 | -- 14. Contestants Submissions 334 | -- Extract from the database, all of the contests and the COUNT of submissions 335 | -- in their problems (IF THERE ARE ANY). 336 | -- Take ONLY the submissions which’s users are still PARTICIPATING in the contest. 337 | -- ORDER the results descending by count of submissions, and ascending by contest id. 338 | -- Required Columns: id (contests), name (contests), submissions 339 | 340 | SELECT 341 | c.id, c.name, COUNT(s.id) AS 'submissions' 342 | FROM 343 | `contests` AS c 344 | JOIN 345 | `problems` AS p ON c.id = p.contest_id 346 | JOIN 347 | `submissions` AS s ON p.id = s.problem_id 348 | JOIN 349 | `users_contests` AS uc ON c.id = uc.contest_id 350 | WHERE 351 | s.user_id = uc.user_id 352 | GROUP BY c.id 353 | ORDER BY `submissions` DESC , c.id; 354 | 355 | -- Solution with inner SELECT clause 356 | SELECT 357 | c.id, c.name, COUNT(s.id) AS 'submissions' 358 | FROM 359 | `contests` AS c 360 | JOIN 361 | `problems` AS p ON c.id = p.contest_id 362 | JOIN 363 | `submissions` AS s ON p.id = s.problem_id 364 | WHERE 365 | s.user_id IN (SELECT 366 | uc.user_id 367 | FROM 368 | `users_contests` AS uc 369 | WHERE 370 | c.id = uc.contest_id) 371 | GROUP BY c.id 372 | ORDER BY `submissions` DESC , c.id; 373 | 374 | 375 | -- 15. Login 376 | -- Create a stored procedure udp_login which accepts the following parameters: 377 | -- username, password 378 | -- And checks the following things: 379 | -- If the username does NOT exist in the users table: 380 | -- Throw an exception with error code ‘45000’ and message ‘Username does not exist!’. 381 | -- If the username exists, but the password is NOT the same: 382 | -- Throw an exception with error code ‘45000’ and message ‘Password is incorrect!’. 383 | -- If the username already exists in the logged_in_users table: 384 | -- Throw an exception with error code ‘45000’ and message ‘User is already logged in!’. 385 | -- If all checks pass, extract the id and the email of the corresponding user, 386 | -- from the users table and INSERT it into the logged_in_users table. 387 | 388 | -- Another way to check user's existence: 389 | -- IF username NOT IN (SELECT u.username FROM `users` S u) THEN .... 390 | 391 | DELIMITER $$ 392 | CREATE PROCEDURE udp_login(username VARCHAR(30), password VARCHAR(30)) 393 | BEGIN 394 | IF ((SELECT u.id FROM `users` AS u WHERE u.username = username) IS NULL) THEN 395 | SIGNAL SQLSTATE '45000' 396 | SET MESSAGE_TEXT = 'Username does not exist!'; 397 | ELSEIF ((SELECT u.id FROM `users` AS u WHERE u.username = username AND u.password = password) IS NULL) THEN 398 | SIGNAL SQLSTATE '45000' 399 | SET MESSAGE_TEXT = 'Password is incorrect!'; 400 | ELSEIF ((SELECT l.id FROM `logged_in_users` AS l WHERE l.username = username) IS NOT NULL) THEN 401 | SIGNAL SQLSTATE '45000' 402 | SET MESSAGE_TEXT = 'User is already logged in!'; 403 | ELSE 404 | INSERT INTO `logged_in_users` SELECT * FROM `users` AS u WHERE u.username = username; 405 | END IF; 406 | END $$ 407 | DELIMITER ; 408 | 409 | CALL udp_login('d', 'doge'); 410 | CALL udp_login('doge', 'd'); 411 | CALL udp_login('doge', 'doge'); 412 | CALL udp_login('doge', 'doge'); 413 | 414 | 415 | -- 16. Evaluate Submission 416 | -- Create a stored procedure udp_evaluate which accepts the following 417 | -- parameters: id (submissions) 418 | -- And evaluates the points which a submission should earn based on its 419 | -- passed_tests and the tests and points of the problem it is submitted to. 420 | -- If there is NO submission with the given id: 421 | -- Throw an exception with error code ‘45000’ and message ‘Submission does not exist!’. 422 | -- If everything passes you should INSERT into the evaluated_submissions table 423 | -- the submission, with its given id, the problem’s name, the user’s username 424 | -- and the result of the submission. 425 | -- The result of the submission is calculated by the following formula: 426 | -- {problem.points} / {problem.tests} * {submission.passed_tests} 427 | -- ROUND the resulting value UP. 428 | -- The problem being the corresponding problem to which the submission is submitted. 429 | 430 | DELIMITER $$ 431 | CREATE PROCEDURE udp_evaluate(id INT(11)) 432 | BEGIN 433 | IF ((SELECT s.id FROM `submissions` AS s WHERE s.id = id) IS NULL) THEN 434 | SIGNAL SQLSTATE '45000' 435 | SET MESSAGE_TEXT = 'Submission does not exist!'; 436 | ELSE 437 | INSERT INTO `evaluated_submissions` 438 | SELECT 439 | s.id, 440 | p.name, 441 | u.username, 442 | CEIL(p.points / p.tests * s.passed_tests) 443 | FROM 444 | (SELECT 445 | * 446 | FROM 447 | `submissions` AS s1 448 | WHERE 449 | s1.id = id) AS s 450 | JOIN 451 | `problems` AS p ON s.problem_id = p.id 452 | JOIN 453 | `users` AS u ON s.user_id = u.id; 454 | END IF; 455 | END $$ 456 | DELIMITER ; 457 | 458 | CALL udp_evaluate(1); 459 | 460 | 461 | -- Section 5: Bonus – 20 pts 462 | 463 | -- 17. Check Constraint 464 | -- Create a trigger, that will help you INSERT more adequate values into the problems table. 465 | -- Upon the insertion of a record into the problems table, the 466 | -- trigger should check the following things: 467 | -- * If the given name does NOT contain at least ONE space (' '): 468 | -- Throw an exception with error code '45000’' and message 469 | -- 'The given name is invalid!' 470 | -- * If the given points are LESS THAN or EQUAL to 0: 471 | -- Throw an exception with error code '45000' and message 472 | -- 'The problem's points cannot be less or equal to 0!' 473 | -- * If the given tests are LESS THAN or EQUAL to 0: 474 | -- Throw an exception with error code '45000' and message 475 | -- 'The problem's tests cannot be less or equal to 0!' 476 | -- If all checks pass successfully, the record should be successfully 477 | -- inserted into the table problems. 478 | -- Submit ONLY the trigger code. 479 | -- The name of the trigger can be anything. 480 | 481 | DELIMITER $$ 482 | CREATE TRIGGER `tr_problems` 483 | BEFORE INSERT ON `problems` 484 | FOR EACH ROW 485 | BEGIN 486 | IF (CHAR_LENGTH(NEW.name) - CHAR_LENGTH(REPLACE(NEW.name, ' ', ''))) < 1 THEN 487 | SIGNAL SQLSTATE '45000' 488 | SET MESSAGE_TEXT = 'The given name is invalid!'; 489 | ELSEIF NEW.points <= 0 THEN 490 | SIGNAL SQLSTATE '45000' 491 | SET MESSAGE_TEXT = 'The problem\'s points cannot be less or equal to 0!'; 492 | ELSEIF NEW.tests <= 0 THEN 493 | SIGNAL SQLSTATE '45000' 494 | SET MESSAGE_TEXT = 'The problem\'s tests cannot be less or equal to 0!'; 495 | END IF; 496 | END $$ 497 | DELIMITER ; 498 | -------------------------------------------------------------------------------- /11. Exam Preparation 3/Bank Skeleton.sql: -------------------------------------------------------------------------------- 1 | -- bank database 2 | CREATE DATABASE bank; 3 | 4 | 5 | USE bank; 6 | 7 | 8 | CREATE TABLE cities( 9 | city_id INT, 10 | city_name VARCHAR(50) NOT NULL, 11 | CONSTRAINT pk_cities PRIMARY KEY(city_id) 12 | ); 13 | 14 | INSERT INTO cities(city_id, city_name) 15 | VALUES 16 | (1,'Povorino'), 17 | (2,'Tanumshede'), 18 | (3,'Santa Mara'), 19 | (4,'Uppsala'), 20 | (5,'Nanpu'), 21 | (6,'Char Bhadrāsan'), 22 | (7,'Darungan Lor'), 23 | (8,'Orlu'), 24 | (9,'Leiden'), 25 | (10,'Rio do Sul'), 26 | (11,'Pinhais'), 27 | (12,'Budapest'), 28 | (13,'Skrunda'), 29 | (14,'Tumaco'), 30 | (15,'Jiangmen'), 31 | (16,'Belyy Yar'), 32 | (17,'Nevers'), 33 | (18,'Boje'), 34 | (19,'Sungaibengkal'), 35 | (20,'Nueva Guadalupe'); 36 | 37 | CREATE TABLE customers( 38 | customer_id INT, 39 | first_name VARCHAR(30) NOT NULL, 40 | last_name VARCHAR(30) NOT NULL, 41 | gender CHAR(1) NOT NULL, 42 | date_of_birth DATE NOT NULL, 43 | height FLOAT, 44 | city_id INT, 45 | CONSTRAINT pk_customers PRIMARY KEY(customer_id), 46 | CONSTRAINT fk_customers_cities FOREIGN KEY(city_id) REFERENCES cities(city_id) 47 | ); 48 | 49 | INSERT INTO customers (customer_id, first_name, last_name, gender, date_of_birth, height, city_id) 50 | VALUES 51 | (1,'Bruce','Armstrong','M','19700917',2.11,10), 52 | (2,'Carolyn','Wells','F','19400623',2.11,18), 53 | (3,'Rachel','White','F','20150611',1.65,9), 54 | (4,'Brenda','Boyd','F','19451125',2.05,17), 55 | (5,'Aaron','Campbell','M','19780806',2.14,7), 56 | (6,'Mary','Gordon','F','19390510',1.66,14), 57 | (7,'Amy','Allen','F','20070425',1.7,11), 58 | (8,'Frank','Armstrong','M','19800520',1.95,20), 59 | (9,'Bobby','Hughes','M','19671012',1.72,8), 60 | (10,'Gregory','Hansen','M','19770816',1.37,4), 61 | (11,'Russell','Lawrence','M','19941117',1.78,3), 62 | (12,'Henry','Henry','M','19451013',1.85,8), 63 | (13,'Christina','Little','F','19540102',1.14,12), 64 | (14,'George','Bennett','M','19560416',2.12,14), 65 | (15,'Carolyn','Pierce','F','20040310',1.89,10), 66 | (16,'Tammy','Crawford','F','19931128',1.46,6), 67 | (17,'Samuel','Cooper','M','20000513',1.22,8), 68 | (18,'Patrick','Mills','M','19740804',2.1,14), 69 | (19,'Matthew','Davis','M','19410901',1.82,8), 70 | (20,'Clarence','Meyer','M','20160123',1.18,12), 71 | (21,'Karen','Mason','F','19570312',2.15,19), 72 | (22,'Lawrence','Diaz','M','19800217',1.78,1), 73 | (23,'Deborah','Taylor','F','19461106',1.5,12), 74 | (24,'Robert','Fuller','M','20030105',2.11,13), 75 | (25,'Debra','Crawford','F','19890524',2.16,1), 76 | (26,'Albert','Flores','M','20050303',1.9,6), 77 | (27,'Howard','Wood','M','19651216',1.11,16), 78 | (28,'Sarah','Wheeler','F','20051103',1.76,11), 79 | (29,'Roy','Rogers','M','19851218',2.14,16), 80 | (30,'John','Pierce','M','19990516',1.01,12), 81 | (31,'Justin','Dixon','M','19560830',1.6,17), 82 | (32,'Karen','Cook','F','19670321',1.93,16), 83 | (33,'Shirley','Williamson','F','19841006',1.62,16), 84 | (34,'Joe','Sanders','M','19720629',1.78,1), 85 | (35,'Mildred','Ferguson','F','19580607',1.34,15), 86 | (36,'Mary','Harper','F','19910330',1.44,15), 87 | (37,'George','Ryan','M','19550809',1.91,13), 88 | (38,'Carl','Turner','M','19750128',1.51,17), 89 | (39,'mark','Wheeler','M','19540202',1.14,1), 90 | (40,'William','Fox','M','19940812',1.92,3); 91 | 92 | 93 | CREATE TABLE accounts( 94 | account_id INT, 95 | account_number CHAR(12) NOT NULL, 96 | start_date DATE NOT NULL, 97 | customer_id INT NOT NULL, 98 | CONSTRAINT pk_accounts PRIMARY KEY(account_id), 99 | CONSTRAINT fk_accounts_customers FOREIGN KEY(customer_id) REFERENCES customers(customer_id) 100 | ); 101 | 102 | INSERT INTO accounts (account_id, account_number, start_date, customer_id) 103 | VALUES 104 | (1,'355074144476','20160422',40), 105 | (2,'510014316471','20151021',13), 106 | (3,'504837572679','20120517',5), 107 | (4,'589360969376','20160723',37), 108 | (5,'357737883238','20151109',5), 109 | (6,'404137269591','20110807',40), 110 | (7,'356665682743','20140323',30), 111 | (8,'353336775123','20110416',24), 112 | (9,'529906064937','20141129',22), 113 | (10,'357300377233','20110402',37), 114 | (11,'501845589067','20160812',16), 115 | (12,'356698459732','20130804',31), 116 | (13,'354165074950','20141227',26), 117 | (14,'358964814991','20120511',30), 118 | (15,'676702537059','20160125',16), 119 | (16,'637847380672','20141115',19), 120 | (17,'501012430845','20151031',2), 121 | (18,'355030411164','20120705',5), 122 | (19,'353551869441','20130612',13), 123 | (20,'358186999628','20130120',36), 124 | (21,'633110998329','20121206',19), 125 | (22,'633110652265','20101203',30), 126 | (23,'357865854277','20110603',19), 127 | (24,'354587535088','20130421',28), 128 | (25,'500766743677','20131011',8), 129 | (26,'670618072040','20150829',33), 130 | (27,'354413268319','20160411',23), 131 | (28,'201924781142','20111213',7), 132 | (29,'353792155017','20130709',31), 133 | (30,'374288725696','20120614',26), 134 | (31,'352806149112','20160805',4), 135 | (32,'355708116263','20140512',37), 136 | (33,'560222129740','20110430',5), 137 | (34,'491305918331','20101013',27), 138 | (35,'676226671786','20120103',26), 139 | (36,'358415634989','20130520',23), 140 | (37,'402677818660','20150909',1), 141 | (38,'375374823869','20110427',6), 142 | (39,'355945632328','20160809',39), 143 | (40,'305517744547','20120125',20); 144 | 145 | CREATE TABLE loans( 146 | loan_id INT AUTO_INCREMENT, 147 | start_date DATE NOT NULL, 148 | amount DECIMAL (18,2) NOT NULL, 149 | interest DECIMAL(4,2) NOT NULL, 150 | expiration_date DATE NULL, 151 | customer_id INT NOT NULL, 152 | CONSTRAINT pk_Loan PRIMARY KEY(loan_id), 153 | CONSTRAINT fk_loans_customers FOREIGN KEY(customer_id) REFERENCES customers(customer_id) 154 | ); 155 | 156 | INSERT INTO loans(loan_id, start_date, amount, interest, expiration_date, customer_id) 157 | VALUES 158 | (1,'20120719',39688.89,0.64,NULL,36), 159 | (2,'20121024',27458.56,0.75,'20140717',39), 160 | (3,'20110522',86354.31,0.96,NULL,40), 161 | (4,'20120415',43669.45,0.84,NULL,15), 162 | (5,'20101103',87303.9,0.19,'20150812',17), 163 | (6,'20110110',21608.36,0.07,'20150913',24), 164 | (7,'20110421',51176.01,0.37,NULL,34), 165 | (8,'20110623',6906.34,0.59,NULL,27), 166 | (9,'20130601',60755.86,0.16,'20131117',2), 167 | (10,'20120528',10153.59,0.74,'20151107',38), 168 | (11,'20120420',33182.13,0.39,'20160320',39), 169 | (12,'20120404',94793.58,0.11,'20150818',30), 170 | (13,'20130513',38042.37,0.12,'20151110',23), 171 | (14,'20130612',64682.27,0.31,'20140403',37), 172 | (15,'20101019',68002.42,0.48,'20160228',2), 173 | (16,'20130704',52386.52,0.09,'20151214',18), 174 | (17,'20110525',51732.28,0.13,'20150408',32), 175 | (18,'20130723',49265.91,0.33,'20150708',37), 176 | (19,'20121224',88067.24,0.23,'20140202',4), 177 | (20,'20120305',30679.99,0.3,NULL,20), 178 | (21,'20110819',72139.46,0.89,NULL,32), 179 | (22,'20130609',9544.91,0.93,NULL,37), 180 | (23,'20111226',50728.08,0.8,NULL,9), 181 | (24,'20101212',3267.54,0.13,'20160509',19), 182 | (25,'20111104',46492.12,0.36,NULL,28), 183 | (26,'20111206',16837.25,0.55,NULL,10), 184 | (27,'20120709',91980.57,0.67,'20160803',34), 185 | (28,'20101010',55077.79,0.84,'20140405',24), 186 | (29,'20130315',89733.18,0.19,NULL,40), 187 | (30,'20110214',58872.88,0.53,'20131003',27), 188 | (31,'20130313',45145.99,0.03,'20131031',27), 189 | (32,'20121011',12684.23,0.08,'20140112',16), 190 | (33,'20110310',92276.06,0.12,'20160806',5), 191 | (34,'20120618',36767.29,0.64,'20141225',29), 192 | (35,'20111004',4114,0.06,'20160310',27), 193 | (36,'20130320',27258.64,0.16,'20160430',21), 194 | (37,'20120404',91384.3,0.88,'20150806',26), 195 | (38,'20120512',19019.01,0.96,'20160115',26), 196 | (39,'20110528',86027.03,0.18,'20131029',29), 197 | (40,'20110615',2163.08,0.67,'20140505',38), 198 | (41,'20130510',9409.06,0.18,'20140927',5), 199 | (42,'20120413',47901.56,0.88,'20131117',2), 200 | (43,'20110609',16449.92,0.04,NULL,26), 201 | (44,'20130304',85025.95,0.56,NULL,28), 202 | (45,'20110614',42992.17,0.91,'20160528',39), 203 | (46,'20110414',57635.73,0.6,'20131122',6), 204 | (47,'20110221',1209.53,0.38,NULL,38), 205 | (48,'20120723',88950.67,0.89,'20160507',21), 206 | (49,'20121230',70819.68,0.2,'20150314',32), 207 | (50,'20120415',12017.63,0.86,'20131006',21); 208 | 209 | 210 | CREATE TABLE branches( 211 | branch_id INT, 212 | name VARCHAR(50), 213 | city_id INT NOT NULL, 214 | CONSTRAINT pk_branches PRIMARY KEY(branch_id), 215 | CONSTRAINT fk_branches_cities FOREIGN KEY(city_id) REFERENCES cities(city_id) 216 | ); 217 | 218 | INSERT INTO branches (branch_id, name, city_id) 219 | VALUES 220 | (1,'Roy',13), 221 | (2,'Roy',8), 222 | (3,'Eugene',8), 223 | (4,'Virginia',15), 224 | (5,'Aaron',14), 225 | (6,'Lois',17), 226 | (7,'Marilyn',13), 227 | (8,'Joseph',9), 228 | (9,'Andrew',18), 229 | (10,'Angela',12), 230 | (11,'Nicole',19), 231 | (12,'Jesse',15), 232 | (13,'Louis',15), 233 | (14,'Pamela',6), 234 | (15,'Nicholas',18), 235 | (16,'Judy',5), 236 | (17,'Lois',15), 237 | (18,'Lois',7), 238 | (19,'Mildred',4), 239 | (20,'Laura',16); 240 | 241 | 242 | CREATE TABLE employees( 243 | employee_id INT, 244 | first_name VARCHAR(50) NOT NULL, 245 | hire_date DATE NOT NULL, 246 | salary DECIMAL(8,2), 247 | branch_id INT, 248 | CONSTRAINT pk_employees PRIMARY KEY(employee_id), 249 | CONSTRAINT fk_employees_branches FOREIGN KEY(branch_id) REFERENCES branches(branch_id) 250 | ); 251 | 252 | INSERT INTO employees (employee_id, first_name, hire_date, salary, branch_id) 253 | VALUES 254 | (1,'Jacqueline','20090114',2263.35,9), 255 | (2,'Kathryn','20080315',1952.32,13), 256 | (3,'Raymond','20060413',2246.48,6), 257 | (4,'Sarah','20060518',2447.09,19), 258 | (5,'Gregory','20091223',2295.88,12), 259 | (6,'Christine','20070218',1554.37,9), 260 | (7,'Laura','20080409',1985.56,15), 261 | (8,'Harry','20060319',2884.21,19), 262 | (9,'Shawn','20090228',2996.61,4), 263 | (10,'Margaret','20060717',2514.07,18), 264 | (11,'Debra','20061008',2569.8,8), 265 | (12,'Gerald','20060613',2107.17,11), 266 | (13,'Walter','20070104',2152.34,3), 267 | (14,'Harold','20080312',2429.6,7), 268 | (15,'Jeremy','20090527',2968.82,12), 269 | (16,'Jessica','20080819',1731.33,13), 270 | (17,'Barbara','20100704',2240.41,10), 271 | (18,'Angela','20070207',2653.56,5), 272 | (19,'Terry','20070409',2530.49,10), 273 | (20,'Ryan','20070712',2401.28,19), 274 | (21,'Michael','20060708',1109.21,19), 275 | (22,'Susan','20090113',2296.28,8), 276 | (23,'Randy','20081014',2925.68,3), 277 | (24,'Anthony','20080526',2416.49,10), 278 | (25,'Deborah','20100105',1902.53,2), 279 | (26,'William','20091121',1639.97,14), 280 | (27,'Jose','20060308',2500.32,17), 281 | (28,'Shawn','20090408',2348.14,13), 282 | (29,'Frances','20080601',2872.45,19), 283 | (30,'Diane','20060318',2574.01,6); 284 | 285 | CREATE TABLE employees_loans( 286 | employee_id INT, 287 | loan_id INT, 288 | CONSTRAINT pk_employees_loans PRIMARY KEY(employee_id, loan_id), 289 | CONSTRAINT fk_employees_loans_customers_employees FOREIGN KEY(employee_id) REFERENCES employees(employee_id), 290 | CONSTRAINT fk_employees_loans_loans FOREIGN KEY(loan_id) REFERENCES loans(loan_id) 291 | ); 292 | 293 | INSERT INTO employees_loans (employee_id, loan_id) 294 | VALUES 295 | (16,34), 296 | (1,34), 297 | (11,30), 298 | (4,45), 299 | (26,39), 300 | (3,14), 301 | (19,16), 302 | (4,26), 303 | (23,19), 304 | (18,35), 305 | (22,17), 306 | (20,11), 307 | (18,15), 308 | (27,30), 309 | (12,11), 310 | (1,8), 311 | (7,9), 312 | (7,6), 313 | (24,24), 314 | (17,9), 315 | (17,36), 316 | (5,31), 317 | (22,33), 318 | (13,5), 319 | (3,4), 320 | (18,34), 321 | (4,14), 322 | (26,49), 323 | (1,14), 324 | (30,7); 325 | 326 | 327 | CREATE TABLE employees_accounts( 328 | employee_id INT, 329 | account_id INT, 330 | CONSTRAINT pk_employees_accounts PRIMARY KEY(employee_id, account_id), 331 | CONSTRAINT fk_employees_accounts_employees FOREIGN KEY(employee_id) REFERENCES employees(employee_id), 332 | CONSTRAINT fk_employees_accounts_Account FOREIGN KEY(account_id) REFERENCES accounts(account_id) 333 | ); 334 | 335 | INSERT INTO employees_accounts (employee_id, account_id) 336 | VALUES 337 | (7,33), 338 | (6,28), 339 | (14,35), 340 | (19,27), 341 | (30,35), 342 | (18,5), 343 | (8,33), 344 | (2,8), 345 | (25,26), 346 | (27,19), 347 | (26,17), 348 | (29,28), 349 | (21,24), 350 | (6,27), 351 | (21,14), 352 | (28,33), 353 | (28,14), 354 | (17,34), 355 | (16,11), 356 | (16,12), 357 | (5,38), 358 | (7,9), 359 | (23,17), 360 | (14,18), 361 | (21,37), 362 | (12,13), 363 | (26,23), 364 | (22,2), 365 | (19,19), 366 | (2,1), 367 | (12,4), 368 | (22,6), 369 | (19,30), 370 | (16,5), 371 | (14,5), 372 | (25,13), 373 | (8,30), 374 | (25,31), 375 | (11,18), 376 | (19,22), 377 | (21,31), 378 | (3,34), 379 | (21,2), 380 | (26,38), 381 | (6,37), 382 | (16,19), 383 | (24,39), 384 | (15,9), 385 | (20,7), 386 | (18,31); -------------------------------------------------------------------------------- /11. Exam Preparation 3/Databases MySQL Exam - 12 Oct 2016.sql: -------------------------------------------------------------------------------- 1 | -- https://judge.softuni.bg/Contests/Practice/Index/319#0 2 | 3 | -- Import all from 'Bank Skeleton.sql' 4 | 5 | USE `bank`; 6 | 7 | -- Section 1. DDL 8 | CREATE TABLE `deposit_types` ( 9 | `deposit_type_id` INT PRIMARY KEY AUTO_INCREMENT, 10 | `name` VARCHAR(20) 11 | ); 12 | 13 | CREATE TABLE `deposits` ( 14 | `deposit_id` INT PRIMARY KEY AUTO_INCREMENT, 15 | `amount` DECIMAL(10 , 2 ), 16 | `start_date` DATE, 17 | `end_date` DATE, 18 | `deposit_type_id` INT, 19 | `customer_id` INT, 20 | CONSTRAINT `fk_deposits_customers` FOREIGN KEY (`customer_id`) 21 | REFERENCES `customers` (`customer_id`), 22 | CONSTRAINT `fk_deposits_deposit_types` FOREIGN KEY (`deposit_type_id`) 23 | REFERENCES `deposit_types` (`deposit_type_id`) 24 | ); 25 | 26 | CREATE TABLE `employees_deposits` ( 27 | `employee_id` INT, 28 | `deposit_id` INT, 29 | CONSTRAINT `pk_employees_deposits` PRIMARY KEY (`employee_id` , `deposit_id`), 30 | CONSTRAINT `fk_employees_deposits_employees` FOREIGN KEY (`employee_id`) 31 | REFERENCES `employees` (`employee_id`), 32 | CONSTRAINT `fk_employees_deposits_deposits` FOREIGN KEY (`deposit_id`) 33 | REFERENCES `deposits` (`deposit_id`) 34 | ); 35 | 36 | CREATE TABLE `credit_history` ( 37 | `credit_history_id` INT PRIMARY KEY AUTO_INCREMENT, 38 | `mark` CHARACTER(1), 39 | `start_date` DATE, 40 | `end_date` DATE, 41 | `customer_id` INT, 42 | CONSTRAINT `fk_credit_history_customers` FOREIGN KEY (`customer_id`) 43 | REFERENCES `customers` (`customer_id`) 44 | ); 45 | 46 | CREATE TABLE `payments` ( 47 | `payement_id` INT PRIMARY KEY AUTO_INCREMENT, 48 | `date` DATE, 49 | `amount` DECIMAL(10 , 2 ), 50 | `loan_id` INT, 51 | CONSTRAINT `fk_payments_loans` FOREIGN KEY (`loan_id`) 52 | REFERENCES `loans` (`loan_id`) 53 | ); 54 | 55 | CREATE TABLE `users` ( 56 | `user_id` INT PRIMARY KEY AUTO_INCREMENT, 57 | `user_name` VARCHAR(20), 58 | `password` VARCHAR(20), 59 | `customer_id` INT UNIQUE, 60 | CONSTRAINT `fk_users_customers` FOREIGN KEY (`customer_id`) 61 | REFERENCES `customers` (`customer_id`) 62 | ); 63 | 64 | ALTER TABLE `employees` 65 | ADD COLUMN `manager_id` INT, 66 | ADD CONSTRAINT `fk_employees_employees` FOREIGN KEY (`manager_id`) 67 | REFERENCES `employees` (`employee_id`); 68 | 69 | 70 | -- Section 2: DML - P01. Inserts 71 | -- Add all customers with ID lower than 20 to table Deposits. 72 | -- The id should be auto generated from table deposits 73 | -- The deposit amount is based on the following logic 74 | -- If you are born after 01-01-1980 then it is 1000 BGN else, it is 1500 BGN 75 | -- If you are Male add 100 BGN else add 200 BGN 76 | -- The start date should be the current date 77 | -- The end should be empty 78 | -- The deposit type id should 1 if the customer id is odd and 2 if the customer id is even. 79 | -- If the customer id is larger than 15 then the deposit type should be 3. 80 | -- The customer id should come from table Customers 81 | 82 | INSERT INTO `deposit_types` VALUES 83 | (1, 'Time Deposit'), 84 | (2, 'Call Deposit'), 85 | (3, 'Free Deposit'); 86 | 87 | INSERT INTO `deposits` 88 | (`amount`, `start_date`, `deposit_type_id`, `customer_id`) 89 | SELECT 90 | (IF(c.date_of_birth > '1980-01-01', 91 | 1000, 92 | 1500) + IF(c.gender = 'M', 100, 200)) AS 'amount', 93 | DATE(NOW()) AS 'start_date', 94 | IF(c.customer_id > 15, 95 | 3, 96 | IF(c.customer_id % 2 = 1, 1, 2)) AS 'deposit_type_id', 97 | c.customer_id 98 | FROM 99 | `customers` AS c 100 | WHERE 101 | c.customer_id < 20; 102 | 103 | INSERT INTO `employees_deposits` 104 | VALUES 105 | (15, 4), 106 | (20, 15), 107 | (8, 7), 108 | (4, 8), 109 | (3, 13), 110 | (3, 8), 111 | (4, 10), 112 | (10, 1), 113 | (13, 4), 114 | (14, 9); 115 | 116 | 117 | -- Section 2: DML - P02. Update 118 | -- Update table Employees. The manager id should have the following values: 119 | -- If EmployeeID is in the range [2;10] then the value is 1 120 | -- If EmployeeID is in the range [12;20] then the value is 11 121 | -- If EmployeeID is in the range [22;30] then the value is 21 122 | -- If EmployeeID is in 11 or 21 then 1 123 | 124 | UPDATE `employees` AS e 125 | SET 126 | e.manager_id = CASE 127 | WHEN e.employee_id BETWEEN 2 AND 11 THEN 1 128 | WHEN e.employee_id BETWEEN 12 AND 20 THEN 11 129 | WHEN e.employee_id = 21 THEN 1 130 | WHEN e.employee_id BETWEEN 22 AND 30 THEN 21 131 | END; 132 | 133 | 134 | -- Section 2: DML - P03. Delete 135 | -- Delete all records from EmployeeDeposits if the DepositID is 9 or the EmployeeID is 3 136 | 137 | DELETE e FROM `employees_deposits` AS e 138 | WHERE 139 | e.deposit_id = 9 OR e.employee_id = 3; 140 | 141 | 142 | -- Section 3: Querying - P01. Employees’ Salary 143 | -- Write a query that returns: employee_id, hire_date, salary, branch_id 144 | -- from table Employees. Filter employees which salaries are higher than 145 | -- 2000 and their hire date is after 15/06/2009. 146 | 147 | SELECT 148 | e.employee_id, e.hire_date, e.salary, e.branch_id 149 | FROM 150 | `employees` AS e 151 | WHERE 152 | e.salary > 2000 153 | AND e.hire_date > '2009-06-15'; 154 | 155 | 156 | -- Section 3: Querying - P02. Customer Age 157 | -- Write a query that returns: first_name, date_of_birth, age 158 | -- of all customers who are between 40 and 50 years old. The range is inclusive. 159 | -- Consider that today is 01-10-2016. Assume that each year has 360 days. 160 | 161 | SELECT 162 | * 163 | FROM 164 | (SELECT 165 | c.first_name, 166 | c.date_of_birth, 167 | FLOOR(DATEDIFF('2016-10-01', c.date_of_birth) / 360) AS 'age' 168 | FROM 169 | `customers` AS c) AS a 170 | WHERE 171 | a.age BETWEEN 40 AND 50; 172 | 173 | 174 | -- Section 3: Querying - P03. Customer City 175 | -- Write a query that returns: customer_id, first_name, last_name, gender, city_name 176 | -- for all customers whose last name starts with ‘Bu’ or first name ends with ‘a’. 177 | -- Moreover, for those customers the length of the city name should at least 8 letters. 178 | -- Sort by CustomerID in ascending order. 179 | 180 | SELECT 181 | c.customer_id, 182 | c.first_name, 183 | c.last_name, 184 | c.gender, 185 | ct.city_name 186 | FROM 187 | `customers` AS c 188 | JOIN 189 | `cities` AS ct ON c.city_id = ct.city_id 190 | WHERE 191 | (c.first_name LIKE '%a' 192 | OR c.last_name LIKE 'Bu%') 193 | AND CHAR_LENGTH(ct.city_name) >= 8 194 | ORDER BY c.customer_id; 195 | 196 | 197 | -- Section 3: Querying - P04. Employee Accounts 198 | -- Write a query that returns top 5: employee_id, first_name, account_number 199 | -- of all employees who are responsible for maintaining accounts which has 200 | -- started after the year of 2012. Sort the results by the first name of the 201 | -- employees in descending order. 202 | 203 | SELECT 204 | e.employee_id, 205 | e.first_name, 206 | a.account_number 207 | FROM 208 | `employees` AS e 209 | JOIN 210 | `employees_accounts` AS ea ON e.employee_id = ea.employee_id 211 | JOIN 212 | `accounts` AS a ON ea.account_id = a.account_id 213 | WHERE 214 | YEAR(a.start_date) > 2012 215 | ORDER BY e.first_name DESC 216 | LIMIT 5; 217 | 218 | 219 | -- Section 3: Querying - P05. Count Cities 220 | -- Write a query that returns: city_name, name (of the branch), employees_count 221 | -- The count of all employees grouped by city name and branch name. 222 | -- Exclude cities with id 4 and 5. Don’t show groups with less than 3 employees. 223 | 224 | SELECT 225 | c.city_name, 226 | b.name, 227 | COUNT(e.employee_id) AS 'employees_count' 228 | FROM 229 | `employees` AS e 230 | JOIN 231 | `branches` AS b ON e.branch_id = b.branch_id 232 | JOIN 233 | `cities` AS c ON b.city_id = c.city_id 234 | WHERE 235 | c.city_id NOT IN (4 , 5) 236 | GROUP BY c.city_name , b.name 237 | HAVING `employees_count` > 2; 238 | 239 | 240 | -- Section 3: Querying - P06. Loan Statistics 241 | -- Write a query that returns: 242 | -- The total amount of loans 243 | -- Max interest of loans 244 | -- Min salary of employees 245 | -- Of all employees that are responsible for maintaining the loans. 246 | 247 | SELECT 248 | SUM(l.amount) AS 'total_loan_amount', 249 | MAX(l.interest) AS 'max_interest', 250 | MIN(e.salary) AS 'min_employee_salary' 251 | FROM 252 | `employees` AS e 253 | JOIN 254 | `employees_loans` AS el ON e.employee_id = el.employee_id 255 | JOIN 256 | `loans` AS l ON el.loan_id = l.loan_id; 257 | 258 | 259 | -- Section 3: Querying - P07. Unite People 260 | -- Write a query that returns top 3 employees’ first names and the city name 261 | -- of their branch followed by top 3 customer’s first names and the name of 262 | -- the city they live in. 263 | 264 | (SELECT 265 | e.first_name, c.city_name 266 | FROM 267 | `employees` AS e 268 | JOIN 269 | `branches` AS b ON e.branch_id = b.branch_id 270 | JOIN 271 | `cities` AS c ON b.city_id = c.city_id 272 | LIMIT 3) UNION (SELECT 273 | c.first_name, ct.city_name 274 | FROM 275 | `customers` AS c 276 | JOIN 277 | `cities` AS ct ON c.city_id = ct.city_id 278 | LIMIT 3); 279 | 280 | 281 | -- Section 3: Querying - P08. Customers w/o Accounts 282 | -- Write a query that returns: customer_id, height 283 | -- of all customers who doesn’t have accounts. 284 | -- Filter only those who are tall between 1.74 and 2.04. 285 | 286 | SELECT 287 | c.customer_id, c.height 288 | FROM 289 | `customers` AS c 290 | LEFT JOIN 291 | `accounts` AS a ON c.customer_id = a.customer_id 292 | WHERE 293 | a.account_id IS NULL 294 | AND c.height BETWEEN 1.74 AND 2.04; 295 | 296 | 297 | -- Section 3: Querying - P09. Average Loans 298 | -- Write a query that returns top 5 rows: customer_id, amount 299 | -- of all customers who have loans higher than the average loan amount of the 300 | -- male customers. Sort the data by customer last name in ascending order 301 | 302 | SELECT 303 | c.customer_id, l.amount 304 | FROM 305 | `loans` AS l 306 | JOIN 307 | `customers` AS c ON l.customer_id = c.customer_id 308 | WHERE 309 | l.amount > (SELECT 310 | AVG(l.amount) 311 | FROM 312 | `loans` AS l 313 | JOIN 314 | `customers` AS c ON l.customer_id = c.customer_id 315 | WHERE 316 | c.gender = 'M') 317 | ORDER BY c.last_name 318 | LIMIT 5; 319 | 320 | 321 | -- Section 3: Querying - P10. Oldest Account 322 | -- Write a query that returns: customer_id, first_name, start_date 323 | -- for the customer with the oldest account. 324 | 325 | SELECT 326 | c.customer_id, c.first_name, a.start_date 327 | FROM 328 | `customers` AS c 329 | JOIN 330 | `accounts` AS a ON c.customer_id = a.customer_id 331 | ORDER BY a.start_date 332 | LIMIT 1; 333 | 334 | 335 | -- Section 4: Programmability - P01. String Joiner 336 | -- Write a function with name udf_concat_string that reverses two strings, 337 | -- joins them and returns the concatenation. The function should have two 338 | -- input parameters of type VARCHAR. 339 | 340 | CREATE FUNCTION udf_concat_string(str1 VARCHAR(50), str2 VARCHAR(50)) 341 | RETURNS VARCHAR(100) 342 | RETURN CONCAT(REVERSE(str1), REVERSE(str2)); 343 | 344 | SELECT udf_concat_string('123', '789'); 345 | 346 | 347 | -- Section 4: Programmability - P02. Inexpired Loans 348 | -- Write a procedure that returns a customer if it has unexpired loan. 349 | -- The following result set should be returned: customer_id, first_name, loan_id 350 | -- The function should have one parameter for customer_id of type integer. 351 | -- Name the function usp_customers_with_unexpired_loans. 352 | -- If the id of the customer doesn’t have unexpired loans return an empty result set. 353 | 354 | DELIMITER $$ 355 | CREATE PROCEDURE usp_customers_with_unexpired_loans(customer_id INT) 356 | BEGIN 357 | SELECT 358 | c.customer_id, c.first_name, l.loan_id 359 | FROM `customers` AS c 360 | JOIN 361 | `loans` AS l ON c.customer_id = l.customer_id 362 | WHERE 363 | c.customer_id = customer_id 364 | AND l.expiration_date IS NULL; 365 | END $$ 366 | DELIMITER ; 367 | 368 | CALL usp_customers_with_unexpired_loans(9); 369 | 370 | 371 | -- Section 4: Programmability - P03. Take Loan 372 | -- Write usp_take_loan procedure that adds a loan to an existing customer. 373 | -- The procedure should have the following input parameters: 374 | -- customer_id, loan_amount, interest, start_date 375 | -- If the loan amount is not between 0.01 AND 100000 raise an error 376 | -- ‘Invalid Loan Amount.’ And rollback the transaction. 377 | -- If no error is raised insert the loan into table Loans. 378 | -- The column loan_id has an auto_increment property so there is no 379 | -- need to specify a value for it. 380 | 381 | DELIMITER $$ 382 | CREATE PROCEDURE usp_take_loan 383 | (customer_id INT, loan_ammount DECIMAL(18,2), interest DECIMAL(4,2), start_date DATE) 384 | BEGIN 385 | IF (loan_ammount NOT BETWEEN 0.01 AND 100000) THEN 386 | SIGNAL SQLSTATE '45000' 387 | SET Message_Text = 'Invalid Loan Amount.'; 388 | ELSE 389 | INSERT INTO `loans` (`start_date`, `amount`, `interest`, `customer_id`) 390 | VALUES (start_date, loan_ammount, interest, customer_id); 391 | END IF; 392 | END $$ 393 | DELIMITER ; 394 | 395 | CALL usp_take_loan (1, 500, 1,'20160915') 396 | 397 | 398 | -- Section 4: Programmability - P04. Hire Employee 399 | -- Write a trigger on table Employees. After an insert of a new employee 400 | -- the new employee takes the loan maintenance of the previous employee. 401 | -- Hint: Your trigger should update table employees_loans 402 | 403 | 404 | DELIMITER $$ 405 | CREATE TRIGGER tr_employees_insert 406 | AFTER INSERT ON `employees` 407 | FOR EACH ROW 408 | BEGIN 409 | UPDATE `employees_loans` AS el 410 | SET el.employee_id = new.employee_id 411 | WHERE el.employee_id + 1= new.employee_id; 412 | END $$ 413 | DELIMITER ; 414 | 415 | 416 | -- Section 5: Bonus - P01. Delete Trigger 417 | -- Create a table with the same structure as table accounts and name it account_logs. 418 | -- Then create a trigger that logs the deleted records from table accounts into table 419 | -- account_logs. Post in judge only the create trigger statement 420 | 421 | CREATE TABLE `account_logs` LIKE `accounts`; 422 | 423 | DELIMITER $$ 424 | CREATE TRIGGER tr_accounts_delete 425 | AFTER DELETE ON `accounts` 426 | FOR EACH ROW 427 | BEGIN 428 | INSERT INTO `account_logs` 429 | VALUES (OLD.account_id, OLD.account_number, OLD.start_date, OLD.customer_id); 430 | END $$ 431 | DELIMITER ; 432 | 433 | -- Test 434 | SET FOREIGN_KEY_CHECKS=0; 435 | DELETE FROM accounts 436 | WHERE customer_id = 4; 437 | SET FOREIGN_KEY_CHECKS=1; 438 | 439 | -- Better solution 440 | DROP TRIGGER IF EXISTS tr_accounts_delete; 441 | 442 | DELIMITER $$ 443 | CREATE TRIGGER tr_accounts_delete 444 | BEFORE DELETE ON `accounts` 445 | FOR EACH ROW 446 | BEGIN 447 | DELETE FROM `employees_accounts` 448 | WHERE account_id = OLD.account_id; 449 | 450 | INSERT INTO `account_logs` 451 | VALUES (OLD.account_id, OLD.account_number, OLD.start_date, OLD.customer_id); 452 | END $$ 453 | DELIMITER ; -------------------------------------------------------------------------------- /11. Exam Preparation 3/Sample-Exam-Bank-12-October-2016.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/11. Exam Preparation 3/Sample-Exam-Bank-12-October-2016.docx -------------------------------------------------------------------------------- /12. Exam/01. Table Design.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Martin-BG/SoftUni-DatabaseBasics-MySQL/2675fa7b625c3de56747c5b46e5a1f5da1169b99/12. Exam/01. Table Design.docx -------------------------------------------------------------------------------- /12. Exam/Database MySQL Exam - 25 February 2018.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE `buhtig`; 2 | 3 | USE `buhtig`; 4 | 5 | -- Section 1: Data Definition Language (DDL) – 40 pts 6 | -- 01. Table Design 7 | 8 | CREATE TABLE `users` ( 9 | `id` INT PRIMARY KEY AUTO_INCREMENT, 10 | `username` VARCHAR(30) UNIQUE NOT NULL, 11 | `password` VARCHAR(30) NOT NULL, 12 | `email` VARCHAR(50) NOT NULL 13 | ); 14 | 15 | CREATE TABLE `repositories` ( 16 | `id` INT PRIMARY KEY AUTO_INCREMENT, 17 | `name` VARCHAR(50) NOT NULL 18 | ); 19 | 20 | CREATE TABLE `repositories_contributors` ( 21 | `repository_id` INT, 22 | `contributor_id` INT, 23 | CONSTRAINT `fk_repositories_contributors_repositories` FOREIGN KEY (`repository_id`) 24 | REFERENCES `repositories` (`id`), 25 | CONSTRAINT `fk_repositories_contributors_users` FOREIGN KEY (`contributor_id`) 26 | REFERENCES `users` (`id`) 27 | ); 28 | 29 | CREATE TABLE `issues` ( 30 | `id` INT PRIMARY KEY AUTO_INCREMENT, 31 | `title` VARCHAR(255) NOT NULL, 32 | `issue_status` VARCHAR(6) NOT NULL, 33 | `repository_id` INT NOT NULL, 34 | `assignee_id` INT NOT NULL, 35 | CONSTRAINT `fk_issues_repositories` FOREIGN KEY (`repository_id`) 36 | REFERENCES `repositories` (`id`), 37 | CONSTRAINT `fk_issues_users` FOREIGN KEY (`assignee_id`) 38 | REFERENCES `users` (`id`) 39 | ); 40 | 41 | CREATE TABLE `commits` ( 42 | `id` INT PRIMARY KEY AUTO_INCREMENT, 43 | `message` VARCHAR(255) NOT NULL, 44 | `issue_id` INT, 45 | `repository_id` INT NOT NULL, 46 | `contributor_id` INT NOT NULL, 47 | CONSTRAINT `fk_commits_issues` FOREIGN KEY (`issue_id`) 48 | REFERENCES `issues` (`id`), 49 | CONSTRAINT `fk_commits_repositories` FOREIGN KEY (`repository_id`) 50 | REFERENCES `repositories` (`id`), 51 | CONSTRAINT `fk_commits_users` FOREIGN KEY (`contributor_id`) 52 | REFERENCES `users` (`id`) 53 | ); 54 | 55 | CREATE TABLE `files` ( 56 | `id` INT PRIMARY KEY AUTO_INCREMENT, 57 | `name` VARCHAR(100) NOT NULL, 58 | `size` DECIMAL(10, 2) NOT NULL, 59 | `parent_id` INT, 60 | `commit_id` INT NOT NULL, 61 | CONSTRAINT `fk_files_files` FOREIGN KEY (`parent_id`) 62 | REFERENCES `files` (`id`), 63 | CONSTRAINT `fk_files_commits` FOREIGN KEY (`commit_id`) 64 | REFERENCES `commits` (`id`) 65 | ); 66 | 67 | 68 | -- Section 2: Data Manipulation Language (DML) – 30 pts 69 | -- 02. Insert 70 | -- You will have to INSERT records of data into the issues table, based on the files table. 71 | -- For files with id between 46 and 50 (inclusive), insert data in the issues table with 72 | -- the following values: 73 | -- title – set it to “Critical Problem With {fileName}!”. Where the fileName is the name 74 | -- of the file. 75 | -- issue_status – set it to “open”. 76 | -- repository_id – MULTIPLY the id of the file by 2 and DIVIDE it by 3. ROUND the resulting 77 | -- value UP. 78 | -- assignee_id – the file’s commit’s contributor’s id. 79 | 80 | 81 | INSERT INTO `issues` 82 | (`title`, `issue_status`, `repository_id`, `assignee_id`) 83 | SELECT 84 | CONCAT('Critical Problem With ', f.name, '!'), 85 | 'open' AS 'issue_status', 86 | CEIL(f.id * 2 / 3) AS 'repository_id', 87 | c.contributor_id AS 'assignee_id' 88 | FROM 89 | `files` AS f 90 | JOIN 91 | `commits` AS c ON f.commit_id = c.id 92 | WHERE 93 | f.id BETWEEN 46 AND 50; 94 | 95 | 96 | -- 03. Update 97 | -- UPDATE all contributors to repositories which have the same id (value) as 98 | -- the repository they contribute to. 99 | -- SET them as a contributor to the repository with the lowest id (by value) 100 | -- which has no contributors. 101 | -- If there aren’t any repositories with no contributors do nothing. 102 | 103 | UPDATE `repositories_contributors` AS rc 104 | JOIN 105 | (SELECT 106 | r.id AS 'repo' 107 | FROM 108 | `repositories` AS r 109 | WHERE 110 | r.id NOT IN (SELECT 111 | repository_id 112 | FROM 113 | `repositories_contributors`) 114 | ORDER BY r.id 115 | LIMIT 1) AS d 116 | SET 117 | rc.repository_id = d.repo 118 | WHERE 119 | rc.contributor_id = rc.repository_id; 120 | 121 | -- 04. Delete 122 | -- Buhtig is all about activity, and activity is expressed in issues. Issues 123 | -- indicate the constant process of development. Naturally, inactive repositories 124 | -- are being treated as abandoned. DELETE all repositories which do NOT have any issues. 125 | 126 | DELETE r FROM `repositories` AS r 127 | LEFT JOIN 128 | `issues` AS i ON r.id = i.repository_id 129 | WHERE 130 | i.id IS NULL; 131 | 132 | 133 | -- Section 3: Querying – 100 pts 134 | -- 05. Users 135 | -- Extract from the database, all of the users. 136 | -- ORDER the results ascending by user id. 137 | -- Required Columns: id (users), username 138 | 139 | SELECT 140 | u.id, u.username 141 | FROM 142 | `users` AS u 143 | ORDER BY u.id; 144 | 145 | 146 | -- 06. Lucky Numbers 147 | -- When a contributor has the same id as the repository he contributes to, it’s a lucky number. 148 | -- Extract from the database, all of the repositories, which have the same id as 149 | -- their contributor. 150 | -- ORDER the results ascending by repository id. 151 | -- Required Columns: repository_id, contributor_id 152 | 153 | SELECT 154 | * 155 | FROM 156 | `repositories_contributors` AS rc 157 | WHERE 158 | rc.contributor_id = rc.repository_id 159 | ORDER BY rc.repository_id; 160 | 161 | 162 | -- 07. Heavy HTML 163 | -- There are some pretty big HTML files in the Buhtig database… Unnaturally big. 164 | -- Extract from the database all of the files, which have size, GREATER than 1000, 165 | -- and their name contains “html”. 166 | -- ORDER the results descending by size. 167 | -- Required Columns: id (files), name, size 168 | 169 | SELECT 170 | f.id, f.name, f.size 171 | FROM 172 | `files` AS f 173 | WHERE 174 | f.size > 1000 AND f.name LIKE '%html%' 175 | ORDER BY f.size DESC; 176 | 177 | 178 | -- 08. IssuesAndUsers 179 | -- Extract from the database, all of the issues, and the users that are assigned to them, 180 | -- so that they end up in the following format: {username} : {issueTitle} 181 | -- ORDER the results descending by issue id. 182 | -- Required Columns: id (issues), issue_assignee 183 | 184 | SELECT 185 | i.id, 186 | CONCAT_WS(' : ', u.username, i.title) AS 'issue_assignee' 187 | FROM 188 | `issues` AS i 189 | JOIN 190 | `users` AS u ON i.assignee_id = u.id 191 | ORDER BY i.id DESC; 192 | 193 | 194 | -- 09. NonDirectoryFiles 195 | -- Some of the files are Directories, because they are a parent to some file. 196 | -- Try to find those, which aren’t. 197 | -- Extract from the database all of the files, which are NOT a parent to any other file. 198 | -- Extract the size of the file and add “KB” to the end of it. 199 | -- ORDER the results ascending by file id. 200 | -- Required Columns: id (files), name, size 201 | 202 | SELECT 203 | f.id, f.name, CONCAT(f.size, 'KB') AS 'size' 204 | FROM 205 | `files` AS f 206 | LEFT JOIN 207 | `files` AS p ON f.id = p.parent_id 208 | WHERE 209 | p.id IS NULL; 210 | 211 | 212 | -- 10. ActiveRepositories 213 | -- Extract from the database, the top 5 repositories, in terms of count of issues on them. 214 | -- ORDER the results descending by issues (count of issues), and ascending by repository id. 215 | -- Required Columns: id (repositories), name (repositories), issues (count of issues) 216 | 217 | SELECT 218 | r.id, r.name, COUNT(i.id) AS 'issues' 219 | FROM 220 | `repositories` AS r 221 | JOIN 222 | `issues` AS i ON r.id = i.repository_id 223 | GROUP BY r.id 224 | ORDER BY `issues` DESC , r.id 225 | LIMIT 5; 226 | 227 | 228 | -- 11. MostContributedRepository 229 | -- Extract from the database, the top 1 repository in terms of count of contributors. 230 | -- If there are 2 repositories have the same count of contributors, order them ascending, by id. 231 | -- Required Columns: id (repositories), name (repositories), commits (count of commits), 232 | -- contributors (count of contributors) 233 | 234 | SELECT 235 | cn.id, r.name, COUNT(c.id) AS 'commits', cn.contributors 236 | FROM 237 | (SELECT 238 | rc.repository_id AS 'id', 239 | COUNT(rc.contributor_id) AS 'contributors' 240 | FROM 241 | `repositories_contributors` AS rc 242 | GROUP BY rc.repository_id) AS cn 243 | JOIN 244 | `repositories` AS r ON cn.id = r.id 245 | LEFT JOIN 246 | `commits` AS c ON cn.id = c.repository_id 247 | GROUP BY cn.id 248 | ORDER BY `contributors` DESC , r.id 249 | LIMIT 1; 250 | 251 | 252 | -- 12. FixingMyOwnProblems 253 | -- Extract from the database, for every user – the count of commits he has on issues that 254 | -- were assigned to him. 255 | -- ORDER the results descending by commits (count of commits), and ascending by user id. 256 | -- Required Columns: id (users), username, commits (count of commits) 257 | 258 | SELECT 259 | u.id, 260 | u.username, 261 | SUM(IF(c.contributor_id = u.id, 1, 0)) AS 'commits' 262 | FROM 263 | `users` AS u 264 | LEFT JOIN 265 | `issues` AS i ON u.id = i.assignee_id 266 | LEFT JOIN 267 | `commits` AS c ON i.id = c.issue_id 268 | GROUP BY u.id 269 | ORDER BY `commits` DESC , u.id; 270 | 271 | -- 13. RecursiveCommits 272 | -- Extract from the database all files which are a parent to their parent. 273 | -- In other words, file “a” is a parent to file “b” and file “b” is a parent to file “a”. 274 | -- Extract the file name (but only the name, without the extension). 275 | -- If its “index.html” you have to extract “index”, as “file”. 276 | -- Extract the count of commits which hold the full file name (with extension) 277 | -- in their messages as “recursive_count”. 278 | -- ORDER the results ascending by file (file name). 279 | -- Required Columns: file (fileName), recursive_count 280 | 281 | SELECT 282 | SUBSTRING_INDEX(f.name, '.', 1) AS 'file', 283 | COUNT(nullif(LOCATE(f.name, c.message), 0)) AS 'recursive_count' 284 | FROM 285 | `files` AS f 286 | JOIN 287 | `files` AS p ON f.parent_id = p.id 288 | JOIN 289 | `commits` AS c 290 | WHERE 291 | f.id <> p.id 292 | AND f.parent_id = p.id 293 | AND p.parent_id = f.id 294 | GROUP BY f.name 295 | ORDER BY f.name; 296 | 297 | 298 | -- 14. RepositoriesAndCommits 299 | -- Extract from the database, for every repository – the count of users 300 | -- that have committed to it. 301 | -- NOTE: 1 user may have more than 1 commit on the repository. 302 | -- ORDER the results descending by users (count of users), and ascending by repository id. 303 | -- Required Columns: id (repositories), name, users (count of users) 304 | 305 | SELECT 306 | r.id, r.name, COUNT(DISTINCT (c.contributor_id)) AS 'users' 307 | FROM 308 | `repositories` AS r 309 | LEFT JOIN 310 | `commits` AS c ON r.id = c.repository_id 311 | GROUP BY r.id 312 | ORDER BY `users` DESC , r.id; 313 | 314 | 315 | -- Section 4: Programmability – 30 pts 316 | -- 15. Commit 317 | -- Create a stored procedure udp_commit which accepts the following parameters: 318 | -- username, password, message, issue_id 319 | -- And checks the following things: 320 | -- If the username does NOT exist in the users table: 321 | -- Throw an exception with error code ‘45000’ and message ‘No such user!’. 322 | -- If the password does NOT match the username in the users table: 323 | -- Throw an exception with error code ‘45000’ and message ‘Password is incorrect!’. 324 | -- If there is no issue with the given id in the issues table: 325 | -- Throw an exception with error code ‘45000’ and message ‘The issue does not exist!’. 326 | -- If all checks pass, extract the id of the corresponding user, 327 | -- from the users table, then the repository_id of the issue, from the issues table, 328 | -- and INSERT a new commit into the commits table with the extracted data. 329 | -- The procedure should also update the issue’s status to ‘closed’. 330 | 331 | DROP PROCEDURE IF EXISTS udp_commit; 332 | 333 | DELIMITER $$ 334 | CREATE PROCEDURE udp_commit 335 | (username VARCHAR(30), password VARCHAR(30), message VARCHAR(255), issue_id INT) 336 | BEGIN 337 | START TRANSACTION; 338 | 339 | IF ((SELECT COUNT(u.id) FROM `users` AS u WHERE u.username = username) = 0) THEN 340 | SIGNAL SQLSTATE '45000' 341 | SET MESSAGE_TEXT = 'No such user!'; 342 | ROLLBACK; 343 | ELSEIF ((SELECT u.password FROM `users` AS u WHERE u.username = username) <> password) THEN 344 | SIGNAL SQLSTATE '45000' 345 | SET MESSAGE_TEXT = 'Password is incorrect!'; 346 | ROLLBACK; 347 | ELSEIF ((SELECT COUNT(i.id) FROM `issues` AS i WHERE i.id = issue_id) = 0) THEN 348 | SIGNAL SQLSTATE '45000' 349 | SET MESSAGE_TEXT = 'The issue does not exist!'; 350 | ROLLBACK; 351 | ELSE 352 | INSERT INTO `commits` 353 | (`message`, `issue_id`, `repository_id`, `contributor_id`) 354 | VALUES 355 | (message, 356 | issue_id, 357 | (SELECT i.repository_id FROM `issues` AS i WHERE i.id = issue_id), 358 | (SELECT u.id FROM `users` AS u WHERE u.username = username)); 359 | UPDATE `issues` AS i 360 | SET 361 | i.issue_status = 'closed' 362 | WHERE 363 | i.id = issue_id; 364 | COMMIT; 365 | END IF; 366 | END $$ 367 | DELIMITER ; 368 | 369 | CALL udp_commit('WhoDenoteBel', 'ajmISQi*', 'Fixed issue: blah', 2); 370 | 371 | 372 | -- 16. Filter Extensions 373 | -- Create a stored procedure udp_findbyextension which accepts the following parameters: 374 | -- extension 375 | -- And extracts all files that have the given extension. (like index.html for example) 376 | -- The procedure should extract the file’s id, name and size. 377 | -- The file’s size should have “KB” attached to it as a suffix. 378 | -- The files should be ordered ascending by file id. 379 | 380 | DROP PROCEDURE IF EXISTS udp_findbyextension; 381 | 382 | DELIMITER $$ 383 | CREATE PROCEDURE udp_findbyextension(extension VARCHAR(100)) 384 | BEGIN 385 | SELECT 386 | f.id, 387 | f.name AS 'caption', 388 | CONCAT(f.size, 'KB') AS 'user' 389 | FROM 390 | `files` AS f 391 | WHERE 392 | f.name LIKE (CONCAT('%', extension)) 393 | ORDER BY f.id; 394 | END $$ 395 | DELIMITER ; 396 | 397 | CALL udp_findbyextension('html'); 398 | 399 | -------------------------------------------------------------------------------- /12. Exam/Reset Database Wth Values.sql: -------------------------------------------------------------------------------- 1 | DROP DATABASE IF EXISTS `buhtig`; 2 | 3 | CREATE DATABASE `buhtig`; 4 | 5 | USE `buhtig`; 6 | 7 | -- Section 1: Data Definition Language (DDL) – 40 pts 8 | -- 01. Table Design 9 | 10 | CREATE TABLE `users` ( 11 | `id` INT PRIMARY KEY AUTO_INCREMENT, 12 | `username` VARCHAR(30) UNIQUE NOT NULL, 13 | `password` VARCHAR(30) NOT NULL, 14 | `email` VARCHAR(50) NOT NULL 15 | ); 16 | 17 | CREATE TABLE `repositories` ( 18 | `id` INT PRIMARY KEY AUTO_INCREMENT, 19 | `name` VARCHAR(50) NOT NULL 20 | ); 21 | 22 | CREATE TABLE `repositories_contributors` ( 23 | `repository_id` INT, 24 | `contributor_id` INT, 25 | CONSTRAINT `fk_repositories_contributors_repositories` FOREIGN KEY (`repository_id`) 26 | REFERENCES `repositories` (`id`), 27 | CONSTRAINT `fk_repositories_contributors_users` FOREIGN KEY (`contributor_id`) 28 | REFERENCES `users` (`id`) 29 | ); 30 | 31 | CREATE TABLE `issues` ( 32 | `id` INT PRIMARY KEY AUTO_INCREMENT, 33 | `title` VARCHAR(255) NOT NULL, 34 | `issue_status` VARCHAR(6) NOT NULL, 35 | `repository_id` INT NOT NULL, 36 | `assignee_id` INT NOT NULL, 37 | CONSTRAINT `fk_issues_repositories` FOREIGN KEY (`repository_id`) 38 | REFERENCES `repositories` (`id`), 39 | CONSTRAINT `fk_issues_users` FOREIGN KEY (`assignee_id`) 40 | REFERENCES `users` (`id`) 41 | ); 42 | 43 | CREATE TABLE `commits` ( 44 | `id` INT PRIMARY KEY AUTO_INCREMENT, 45 | `message` VARCHAR(255) NOT NULL, 46 | `issue_id` INT, 47 | `repository_id` INT NOT NULL, 48 | `contributor_id` INT NOT NULL, 49 | CONSTRAINT `fk_commits_issues` FOREIGN KEY (`issue_id`) 50 | REFERENCES `issues` (`id`), 51 | CONSTRAINT `fk_commits_repositories` FOREIGN KEY (`repository_id`) 52 | REFERENCES `repositories` (`id`), 53 | CONSTRAINT `fk_commits_users` FOREIGN KEY (`contributor_id`) 54 | REFERENCES `users` (`id`) 55 | ); 56 | 57 | CREATE TABLE `files` ( 58 | `id` INT PRIMARY KEY AUTO_INCREMENT, 59 | `name` VARCHAR(100) NOT NULL, 60 | `size` DECIMAL(10, 2) NOT NULL, 61 | `parent_id` INT, 62 | `commit_id` INT NOT NULL, 63 | CONSTRAINT `fk_files_files` FOREIGN KEY (`parent_id`) 64 | REFERENCES `files` (`id`), 65 | CONSTRAINT `fk_files_commits` FOREIGN KEY (`commit_id`) 66 | REFERENCES `commits` (`id`) 67 | ); 68 | 69 | 70 | INSERT INTO users (id, username, password, email) 71 | VALUES 72 | (1, 'UnderSinduxrein', '4l8nYGTKMW', 'azfex@gmail.com'), 73 | (2, 'BlaAntigadsa', ':Q5wjT4[e', 'kuf@abv.bg'), 74 | (3, 'ANinedsa', 'El[MwhxY)J', 'indie@yahoo.com'), 75 | (4, 'ScoreImmagidefon', '`NGU>oS', 'daffy@yandex.bg'), 76 | (5, 'BlaSinduxrein', 'wJyfcwg*', 'toni@donald.eu'), 77 | (6, 'WhoDenoteBel', 'ajmISQi*', 'tinny@pd.cd'), 78 | (7, 'WhatTerrorBel', 'R+-<+..Pl3j^', 'joseph@lon.co.uk'), 79 | (8, 'AryaDenotehow', 'NNY57EUNeUC@kv', 'diplomat@po.bo'), 83 | (12, 'DarkImmagidsa', 'R.fh[f1Zh>2', 'sys@admin.bg'), 84 | (13, 'RoundInspecindi', 'AdKs>q]u7P`C', 'katr@kiper.eu'), 85 | (14, 'AryaNinehow', 'X6j>`Huf2F(I', 'wrec@soft.wrap'), 86 | (15, 'ScoreAntigarein', 'UUD3H))<', 'dec@int.float'), 87 | (16, 'TheDivineBel', '-gCi:_Ub?ypT', 'rindiy@abv.bg'), 88 | (17, 'RoundArmydsa', 'SZ?F-:hW', 'com@gmail.user'), 89 | (18, 'HighAsmahow', 'lyqF\vUG', 'svik@kiwi.mandarin'), 90 | (19, 'ZendArmyhow', 'DbW>9,', 'rip@pob.cid'), 91 | (20, 'BlaImmagiIana', 'upE;fg6+)n', 'stun@asd.cdd'); 92 | 93 | INSERT INTO repositories (id, name) 94 | VALUES 95 | (1, 'WorkWork'), 96 | (2, 'Tumbalore'), 97 | (3, 'Softuni-Teamwork'), 98 | (4, 'IncreaseRepo'), 99 | (5, 'ContinuousIntegration'), 100 | (6, 'IndigoDB'), 101 | (7, 'DundaApp'), 102 | (8, 'Citros'), 103 | (9, 'BogoApp'), 104 | (10, 'SortedTupleJS'), 105 | (11, 'KartinaJS'), 106 | (12, 'SpiralSort'), 107 | (13, 'Vendigo-RPG'), 108 | (14, 'Kartica'), 109 | (15, 'SignalR'), 110 | (16, 'ASP.NET'), 111 | (17, 'MySQL'), 112 | (18, 'InnoDB'), 113 | (19, 'Catalina'), 114 | (20, 'JosephineDB'), 115 | (21, 'Intrigued-RPG'), 116 | (22, 'Maxima'), 117 | (23, 'Calculus'), 118 | (24, 'Assembly-Force'), 119 | (25, 'Mesmerize-Frameowork'), 120 | (26, 'maxOut'), 121 | (27, 'inspiration'), 122 | (28, 'Bau'), 123 | (29, 'Practiq'), 124 | (30, 'Daun'), 125 | (31, 'Kimmers'), 126 | (32, 'Defalte_pf'), 127 | (33, 'Kras_par_ti'), 128 | (34, 'Antiq'), 129 | (35, 'Dantelle'), 130 | (36, 'DELET THIS'); 131 | 132 | INSERT INTO repositories_contributors(repository_id, contributor_id) 133 | VALUES 134 | (2, 15), 135 | (26, 16), 136 | (30, 2), 137 | (16, 11), 138 | (10, 15), 139 | (28, 17), 140 | (7, 19), 141 | (22, 3), 142 | (16, 4), 143 | (25, 15), 144 | (18, 5), 145 | (30, 17), 146 | (1, 14), 147 | (1, 1), 148 | (27, 1), 149 | (12, 2), 150 | (2, 16), 151 | (16, 18), 152 | (33, 12), 153 | (30, 1), 154 | (15, 17), 155 | (3, 1), 156 | (14, 4), 157 | (28, 16), 158 | (24, 15), 159 | (29, 3), 160 | (32, 19), 161 | (3, 14), 162 | (10, 2), 163 | (13, 15), 164 | (7, 1), 165 | (15, 9), 166 | (22, 5), 167 | (5, 9), 168 | (32, 16), 169 | (25, 6), 170 | (9, 13), 171 | (29, 15), 172 | (33, 14), 173 | (9, 9), 174 | (3, 3), 175 | (22, 4), 176 | (8, 5), 177 | (21, 13), 178 | (29, 5), 179 | (5, 2), 180 | (22, 10), 181 | (2, 1), 182 | (10, 19), 183 | (17, 4), 184 | (7, 7), 185 | (20, 6), 186 | (11, 1), 187 | (18, 16), 188 | (23, 18), 189 | (32, 14), 190 | (28, 13), 191 | (29, 6), 192 | (14, 7), 193 | (1, 18), 194 | (1, 10), 195 | (26, 1), 196 | (5, 12), 197 | (34, 17), 198 | (21, 3), 199 | (8, 16), 200 | (31, 13), 201 | (13, 1), 202 | (14, 8), 203 | (13, 9), 204 | (1, 6), 205 | (32, 8), 206 | (25, 12), 207 | (19, 15), 208 | (30, 12), 209 | (30, 11), 210 | (2, 3), 211 | (24, 1), 212 | (22, 9), 213 | (34, 14), 214 | (31, 16), 215 | (11, 7), 216 | (27, 10), 217 | (6, 1), 218 | (31, 1), 219 | (4, 14), 220 | (30, 19), 221 | (6, 15), 222 | (16, 2), 223 | (10, 3), 224 | (3, 17), 225 | (9, 5), 226 | (13, 7), 227 | (7, 6), 228 | (22, 8), 229 | (23, 19), 230 | (26, 11), 231 | (3, 7), 232 | (33, 1), 233 | (27, 2); 234 | 235 | INSERT INTO issues(id, title, issue_status, repository_id, assignee_id) 236 | VALUES 237 | (1, 'Invalid welcoming message in Controller.json', 'closed', 25, 5), 238 | (2, 'Invalid welcoming message in READ.html', 'opened', 34, 13), 239 | (3, 'Unreachable code in Find.java stops compilation flow', 'closed', 11, 11), 240 | (4, 'Implement documentation for Jason.exe module', 'closed', 16, 5), 241 | (5, 'Unreachable code in Model.MD stops compilation flow', 'closed', 6, 17), 242 | (6, 'Security Flaw in Accelerate.dd inner code', 'opened', 5, 14), 243 | (7, 'Compilation failed while trying to execute Bean.php', 'closed', 14, 14), 244 | (8, 'Critical bug in sound.sick ruins application when executed', 'opened', 24, 11), 245 | (9, 'Invalid welcoming message in Find.java', 'clear', 25, 12), 246 | (10, 'Unreachable code in Index.class stops compilation flow', 'clear', 24, 4), 247 | (11, 'Loose Cohesion and Strong Coupling in Beat.bat', 'clear', 34, 7), 248 | (12, 'Compilation failed while trying to execute READ.img', 'closed', 16, 1), 249 | (13, 'Critical bug in pipeline.dd ruins application when executed', 'clear', 3, 16), 250 | (14, 'Implement documentation for Register.py module', 'clear', 1, 17), 251 | (15, 'Compilation failed while trying to execute Search.py', 'clear', 19, 1), 252 | (16, 'Inappropriate prompt from READ.html', 'fixed', 8, 1), 253 | (17, 'Unreachable code in index.intro stops compilation flow', 'opened', 22, 9), 254 | (18, 'Critical bug in Jason.exe ruins application when executed', 'opened', 29, 14), 255 | (19, 'Compilation failed while trying to execute Beat.bat', 'closed', 10, 18), 256 | (20, 'init.txt breaks down after startup', 'fixed', 4, 10), 257 | (21, 'compile.png breaks down after startup', 'clear', 7, 9), 258 | (22, 'Unreachable code in index.net stops compilation flow', 'fixed', 16, 9), 259 | (23, 'Inappropriate prompt from index.net', 'closed', 18, 1), 260 | (24, 'Implement documentation for index.intro module', 'closed', 9, 11), 261 | (25, 'Invalid welcoming message in file.sick', 'clear', 20, 5), 262 | (26, 'Unreachable code in Login.html stops compilation flow', 'fixed', 27, 1), 263 | (27, 'Hotfix for security issue in View.dd introduces new security issue', 'clear', 30, 6), 264 | (28, 'Hotfix for security issue in Jason.exe introduces new security issue', 'closed', 15, 2), 265 | (29, 'Loose Cohesion and Strong Coupling in READ.img', 'fixed', 13, 8), 266 | (30, 'Inappropriate prompt from config.dd', 'fixed', 29, 12), 267 | (31, 'Invalid welcoming message in Administrate.soshy', 'closed', 12, 10), 268 | (32, 'Hotfix for security issue in Index.class introduces new security issue', 'clear', 5, 16), 269 | (33, 'Loose Cohesion and Strong Coupling in Bean.php', 'clear', 19, 8), 270 | (34, 'Loose Cohesion and Strong Coupling in file.png', 'closed', 14, 16), 271 | (35, 'Invalid welcoming message in Accelerate.sick', 'clear', 17, 14), 272 | (36, 'Compilation failed while trying to execute index.intro', 'clear', 11, 19), 273 | (37, 'Security Flaw in Music.jpg inner code', 'closed', 11, 11), 274 | (38, 'index.db breaks down after startup', 'closed', 23, 8), 275 | (39, 'Unreachable code in Music.jpg stops compilation flow', 'clear', 5, 19), 276 | (40, 'Unimplemented exception thrown in Accelerate.sick', 'clear', 20, 1), 277 | (41, 'Invalid welcoming message in Search.py', 'clear', 32, 14), 278 | (42, 'Invalid welcoming message in index.cpp', 'clear', 26, 15), 279 | (43, 'Compilation failed while trying to execute index.db', 'clear', 15, 1), 280 | (44, 'Root.net breaks down after startup', 'fixed', 31, 5), 281 | (45, 'Unimplemented exception thrown in init.txt', 'clear', 30, 2), 282 | (46, 'Critical bug in compile.html ruins application when executed', 'opened', 3, 11), 283 | (47, 'Inappropriate prompt from index.db', 'clear', 30, 14), 284 | (48, 'Implement documentation for file.cpp module', 'opened', 12, 14), 285 | (49, 'Inappropriate prompt from Register.py', 'fixed', 9, 2), 286 | (50, 'Implement documentation for index.db module', 'fixed', 17, 7), 287 | (51, 'Critical bug in Trade.idk ruins application when executed', 'clear', 27, 13), 288 | (52, 'Unimplemented exception thrown in Beat.xix', 'fixed', 16, 6), 289 | (53, 'Unimplemented exception thrown in Administrate.go', 'clear', 1, 17), 290 | (54, 'Unimplemented exception thrown in Login.html', 'clear', 32, 1), 291 | (55, 'Unreachable code in Register.py stops compilation flow', 'opened', 21, 18), 292 | (56, 'Hotfix for security issue in pipeline.dd introduces new security issue', 'fixed', 27, 17), 293 | (57, 'Invalid welcoming message in init.txt', 'fixed', 14, 15), 294 | (58, 'Implement documentation for Administrate.soshy module', 'opened', 28, 1), 295 | (59, 'Hotfix for security issue in index.soshy introduces new security issue', 'closed', 11, 3), 296 | (60, 'Implement documentation for file.sick module', 'closed', 31, 10), 297 | (61, 'Loose Cohesion and Strong Coupling in Root.net', 'closed', 13, 7), 298 | (62, 'Compilation failed while trying to execute index.net', 'opened', 8, 19), 299 | (63, 'Unimplemented exception thrown in Register.py', 'clear', 21, 19), 300 | (64, 'file.sick breaks down after startup', 'closed', 35, 19), 301 | (65, 'Security Flaw in pipeline.dd inner code', 'opened', 3, 19), 302 | (66, 'Invalid welcoming message in index.intro', 'closed', 8, 6), 303 | (67, 'Security Flaw in Beat.xix inner code', 'opened', 33, 7), 304 | (68, 'Inappropriate prompt from compile.ivory', 'clear', 11, 4), 305 | (69, 'Inappropriate prompt from Search.py', 'clear', 12, 17), 306 | (70, 'Hotfix for security issue in Login.db introduces new security issue', 'clear', 2, 19), 307 | (71, 'Implement documentation for Index.class module', 'closed', 32, 3), 308 | (72, 'Loose Cohesion and Strong Coupling in index.soshy', 'opened', 29, 12), 309 | (73, 'Loose Cohesion and Strong Coupling in Beat.html', 'opened', 2, 15), 310 | (74, 'Compilation failed while trying to execute init.xml', 'opened', 24, 12), 311 | (75, 'Critical bug in Controller.php ruins application when executed', 'fixed', 8, 16); 312 | 313 | INSERT INTO commits(id, message, issue_id, repository_id, contributor_id) 314 | VALUES 315 | (1, 'Deleted deprecated functionality from index.cpp', 58, 17, 8), 316 | (2, 'Created README.MD', 15, 14, 8), 317 | (3, 'Initial Commit', 52, 24, 1), 318 | (4, 'Implemented config.json functionality', 15, 10, 12), 319 | (5, 'Deleted deprecated functionality from index.dd', 32, 13, 18), 320 | (6, 'Hotfix for bug in Index.class', 71, 19, 1), 321 | (7, 'Patch Index.javav.', 38, 8, 11), 322 | (8, 'Deleted deprecated functionality from Operate.xix', NULL, 28, 9), 323 | (9, 'Fixed security issue in file.png', NULL, 6, 2), 324 | (10, 'Deleted deprecated functionality from index.net', NULL, 27, 1), 325 | (11, 'Patch Model.MDv.', 52, 7, 16), 326 | (12, 'Deleted deprecated functionality from Music.jpg', 41, 6, 11), 327 | (13, 'Implemented index.net functionality', NULL, 15, 11), 328 | (14, 'Fixed index.dd', 40, 1, 7), 329 | (15, 'Fixed index.soshy', NULL, 19, 1), 330 | (16, 'Patch Operate.xixv.', NULL, 21, 4), 331 | (17, 'Hotfix for bug in Database.dd', 73, 14, 11), 332 | (18, 'Hotfix for bug in init.xml', 3, 10, 11), 333 | (19, 'Hotfix for bug in compile.png', 2, 7, 3), 334 | (20, 'Fixed init.xml', 15, 30, 15), 335 | (21, 'Hotfix for bug in Administrate.soshy', 8, 26, 19), 336 | (22, 'Implemented Index.class functionality', NULL, 14, 13), 337 | (23, 'Fixed security issue in Beat.bat', NULL, 7, 4), 338 | (24, 'Patch index.netv.', 36, 16, 14), 339 | (25, 'Implemented compile.png functionality', 21, 10, 2), 340 | (26, 'Fixed security issue in compile.html', 72, 22, 4), 341 | (27, 'Patch index.ddv.', 62, 6, 3), 342 | (28, 'Fixed Controller.php', 4, 9, 7), 343 | (29, 'Patch Find.javav.', 29, 28, 4), 344 | (30, 'Hotfix for bug in compile.ivory', 43, 25, 14), 345 | (31, 'Fixed security issue in compile.png', 64, 16, 10), 346 | (32, 'Implemented Beat.bat functionality', NULL, 5, 18), 347 | (33, 'Patch Database.ddv.', 17, 4, 15), 348 | (34, 'Deleted deprecated functionality from Model.MD', 48, 17, 7), 349 | (35, 'Patch init.txtv.', 51, 11, 2), 350 | (36, 'Fixed menu.net', 48, 3, 18), 351 | (37, 'Implemented Find.java functionality', NULL, 1, 1), 352 | (38, 'Deleted deprecated functionality from index.intro', 70, 18, 16), 353 | (39, 'Implemented Beat.html functionality', 51, 1, 5), 354 | (40, 'Deleted deprecated functionality from Database.dd', NULL, 2, 13), 355 | (41, 'Implemented Trade.idk functionality', NULL, 15, 19), 356 | (42, 'Hotfix for bug in compile.html', 15, 6, 19), 357 | (43, 'Fixed security issue in Search.py', 17, 21, 15), 358 | (44, 'Fixed security issue in Accelerate.sick', 20, 2, 17), 359 | (45, 'Fixed security issue in Administrate.soshy', 58, 25, 1), 360 | (46, 'Fixed security issue in file.txt', NULL, 1, 14), 361 | (47, 'Fixed Operate.xix', 29, 27, 15), 362 | (48, 'Implemented init.xml functionality', 39, 7, 17), 363 | (49, 'Fixed config.json', 1, 28, 5), 364 | (50, 'Implemented Database.dd functionality', NULL, 29, 8); 365 | 366 | INSERT INTO files(id, name, size, parent_id, commit_id) 367 | VALUES 368 | (1, 'Trade.idk', 2598.0, 1, 1), 369 | (2, 'menu.net', 9238.31, 2, 2), 370 | (3, 'Administrate.soshy', 1246.93, 3, 3), 371 | (4, 'Controller.php', 7353.15, 4, 4), 372 | (5, 'Find.java', 9957.86, 5, 5), 373 | (6, 'Controller.json', 14034.87, 3, 6), 374 | (7, 'Operate.xix', 7662.92, 7, 7), 375 | (8, 'file.sick', 10548.35, 8, 8), 376 | (9, 'config.dd', 8745.77, 9, 9), 377 | (10, 'Index.java', 6121.35, 10, 10), 378 | (11, 'compile.ivory', 1185.04, 11, 1), 379 | (12, 'Model.MD', 4753.67, 3, 12), 380 | (13, 'Beat.html', 907.3, 13, 13), 381 | (14, 'READ.img', 2627.6, 14, 7), 382 | (15, 'Search.py', 8831.43, 15, 15), 383 | (16, 'Controller.intro', 27302.85, 11, 1), 384 | (17, 'Login.html', 2863.23, 16, 17), 385 | (18, 'Administrate.go', 24612.57, 9, 18), 386 | (19, 'READ.html', 2396.47, 8, 1), 387 | (20, 'index.net', 9261.71, 20, 20), 388 | (21, 'Index.class', 4001.15, 21, 21), 389 | (22, 'config.json', 6049.09, 22, 22), 390 | (23, 'pipeline.dd', 18407.72, NULL, 19), 391 | (24, 'Accelerate.dd', 23042.88, 24, 19), 392 | (25, 'Database.dd', 14905.56, NULL, 25), 393 | (26, 'Login.db', 8015.83, NULL, 21), 394 | (27, 'Beat.bat', 21431.98, 25, 12), 395 | (28, 'Jason.txt', 10317.54, NULL, 28), 396 | (29, 'Jason.exe', 28209.18, 8, 25), 397 | (30, 'Accelerate.idk', 5520.3, 30, 1), 398 | (31, 'file.txt', 5514.02, 27, 1), 399 | (32, 'Music.jpg', 917.75, 1, 3), 400 | (33, 'Root.net', 6784.97, 8, 28), 401 | (34, 'sound.sick', 8749.82, 20, 16), 402 | (35, 'index.dd', 35942.21, NULL, 35), 403 | (36, 'index.intro', 14325.29, 26, 36), 404 | (37, 'init.xml', 40028.01, NULL, 22), 405 | (38, 'file.cpp', 3038.23, NULL, 22), 406 | (39, 'Beat.xix', 5877.21, 22, 31), 407 | (40, 'index.cpp', 28912.18, 2, 40), 408 | (41, 'compile.png', 20510.09, 22, 24), 409 | (42, 'Register.py', 2037.26, 5, 27), 410 | (43, 'init.txt', 16089.79, 28, 4), 411 | (44, 'View.dd', 2470.36, NULL, 44), 412 | (45, 'file.png', 7755.49, NULL, 23), 413 | (46, 'index.db', 3821.36, 11, 46), 414 | (47, 'Accelerate.sick', 5774.32, 47, 47), 415 | (48, 'index.soshy', 30522.96, 30, 26), 416 | (49, 'compile.html', 27402.59, 28, 24), 417 | (50, 'Bean.php', 4184.45, 20, 35); 418 | 419 | UPDATE files 420 | SET parent_id = 42 421 | WHERE id = 5; -------------------------------------------------------------------------------- /12. Exam/dataset-2.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO users (id, username, password, email) 2 | VALUES 3 | (1, 'UnderSinduxrein', '4l8nYGTKMW', 'azfex@gmail.com'), 4 | (2, 'BlaAntigadsa', ':Q5wjT4[e', 'kuf@abv.bg'), 5 | (3, 'ANinedsa', 'El[MwhxY)J', 'indie@yahoo.com'), 6 | (4, 'ScoreImmagidefon', '`NGU>oS', 'daffy@yandex.bg'), 7 | (5, 'BlaSinduxrein', 'wJyfcwg*', 'toni@donald.eu'), 8 | (6, 'WhoDenoteBel', 'ajmISQi*', 'tinny@pd.cd'), 9 | (7, 'WhatTerrorBel', 'R+-<+..Pl3j^', 'joseph@lon.co.uk'), 10 | (8, 'AryaDenotehow', 'NNY57EUNeUC@kv', 'diplomat@po.bo'), 14 | (12, 'DarkImmagidsa', 'R.fh[f1Zh>2', 'sys@admin.bg'), 15 | (13, 'RoundInspecindi', 'AdKs>q]u7P`C', 'katr@kiper.eu'), 16 | (14, 'AryaNinehow', 'X6j>`Huf2F(I', 'wrec@soft.wrap'), 17 | (15, 'ScoreAntigarein', 'UUD3H))<', 'dec@int.float'), 18 | (16, 'TheDivineBel', '-gCi:_Ub?ypT', 'rindiy@abv.bg'), 19 | (17, 'RoundArmydsa', 'SZ?F-:hW', 'com@gmail.user'), 20 | (18, 'HighAsmahow', 'lyqF\vUG', 'svik@kiwi.mandarin'), 21 | (19, 'ZendArmyhow', 'DbW>9,', 'rip@pob.cid'), 22 | (20, 'BlaImmagiIana', 'upE;fg6+)n', 'stun@asd.cdd'); 23 | 24 | INSERT INTO repositories (id, name) 25 | VALUES 26 | (1, 'WorkWork'), 27 | (2, 'Tumbalore'), 28 | (3, 'Softuni-Teamwork'), 29 | (4, 'IncreaseRepo'), 30 | (5, 'ContinuousIntegration'), 31 | (6, 'IndigoDB'), 32 | (7, 'DundaApp'), 33 | (8, 'Citros'), 34 | (9, 'BogoApp'), 35 | (10, 'SortedTupleJS'), 36 | (11, 'KartinaJS'), 37 | (12, 'SpiralSort'), 38 | (13, 'Vendigo-RPG'), 39 | (14, 'Kartica'), 40 | (15, 'SignalR'), 41 | (16, 'ASP.NET'), 42 | (17, 'MySQL'), 43 | (18, 'InnoDB'), 44 | (19, 'Catalina'), 45 | (20, 'JosephineDB'), 46 | (21, 'Intrigued-RPG'), 47 | (22, 'Maxima'), 48 | (23, 'Calculus'), 49 | (24, 'Assembly-Force'), 50 | (25, 'Mesmerize-Frameowork'), 51 | (26, 'maxOut'), 52 | (27, 'inspiration'), 53 | (28, 'Bau'), 54 | (29, 'Practiq'), 55 | (30, 'Daun'), 56 | (31, 'Kimmers'), 57 | (32, 'Defalte_pf'), 58 | (33, 'Kras_par_ti'), 59 | (34, 'Antiq'), 60 | (35, 'Dantelle'), 61 | (36, 'DELET THIS'); 62 | 63 | INSERT INTO repositories_contributors(repository_id, contributor_id) 64 | VALUES 65 | (2, 15), 66 | (26, 16), 67 | (30, 2), 68 | (16, 11), 69 | (10, 15), 70 | (28, 17), 71 | (7, 19), 72 | (22, 3), 73 | (16, 4), 74 | (25, 15), 75 | (18, 5), 76 | (30, 17), 77 | (1, 14), 78 | (1, 1), 79 | (27, 1), 80 | (12, 2), 81 | (2, 16), 82 | (16, 18), 83 | (33, 12), 84 | (30, 1), 85 | (15, 17), 86 | (3, 1), 87 | (14, 4), 88 | (28, 16), 89 | (24, 15), 90 | (29, 3), 91 | (32, 19), 92 | (3, 14), 93 | (10, 2), 94 | (13, 15), 95 | (7, 1), 96 | (15, 9), 97 | (22, 5), 98 | (5, 9), 99 | (32, 16), 100 | (25, 6), 101 | (9, 13), 102 | (29, 15), 103 | (33, 14), 104 | (9, 9), 105 | (3, 3), 106 | (22, 4), 107 | (8, 5), 108 | (21, 13), 109 | (29, 5), 110 | (5, 2), 111 | (22, 10), 112 | (2, 1), 113 | (10, 19), 114 | (17, 4), 115 | (7, 7), 116 | (20, 6), 117 | (11, 1), 118 | (18, 16), 119 | (23, 18), 120 | (32, 14), 121 | (28, 13), 122 | (29, 6), 123 | (14, 7), 124 | (1, 18), 125 | (1, 10), 126 | (26, 1), 127 | (5, 12), 128 | (34, 17), 129 | (21, 3), 130 | (8, 16), 131 | (31, 13), 132 | (13, 1), 133 | (14, 8), 134 | (13, 9), 135 | (1, 6), 136 | (32, 8), 137 | (25, 12), 138 | (19, 15), 139 | (30, 12), 140 | (30, 11), 141 | (2, 3), 142 | (24, 1), 143 | (22, 9), 144 | (34, 14), 145 | (31, 16), 146 | (11, 7), 147 | (27, 10), 148 | (6, 1), 149 | (31, 1), 150 | (4, 14), 151 | (30, 19), 152 | (6, 15), 153 | (16, 2), 154 | (10, 3), 155 | (3, 17), 156 | (9, 5), 157 | (13, 7), 158 | (7, 6), 159 | (22, 8), 160 | (23, 19), 161 | (26, 11), 162 | (3, 7), 163 | (33, 1), 164 | (27, 2); 165 | 166 | INSERT INTO issues(id, title, issue_status, repository_id, assignee_id) 167 | VALUES 168 | (1, 'Invalid welcoming message in Controller.json', 'closed', 25, 5), 169 | (2, 'Invalid welcoming message in READ.html', 'opened', 34, 13), 170 | (3, 'Unreachable code in Find.java stops compilation flow', 'closed', 11, 11), 171 | (4, 'Implement documentation for Jason.exe module', 'closed', 16, 5), 172 | (5, 'Unreachable code in Model.MD stops compilation flow', 'closed', 6, 17), 173 | (6, 'Security Flaw in Accelerate.dd inner code', 'opened', 5, 14), 174 | (7, 'Compilation failed while trying to execute Bean.php', 'closed', 14, 14), 175 | (8, 'Critical bug in sound.sick ruins application when executed', 'opened', 24, 11), 176 | (9, 'Invalid welcoming message in Find.java', 'clear', 25, 12), 177 | (10, 'Unreachable code in Index.class stops compilation flow', 'clear', 24, 4), 178 | (11, 'Loose Cohesion and Strong Coupling in Beat.bat', 'clear', 34, 7), 179 | (12, 'Compilation failed while trying to execute READ.img', 'closed', 16, 1), 180 | (13, 'Critical bug in pipeline.dd ruins application when executed', 'clear', 3, 16), 181 | (14, 'Implement documentation for Register.py module', 'clear', 1, 17), 182 | (15, 'Compilation failed while trying to execute Search.py', 'clear', 19, 1), 183 | (16, 'Inappropriate prompt from READ.html', 'fixed', 8, 1), 184 | (17, 'Unreachable code in index.intro stops compilation flow', 'opened', 22, 9), 185 | (18, 'Critical bug in Jason.exe ruins application when executed', 'opened', 29, 14), 186 | (19, 'Compilation failed while trying to execute Beat.bat', 'closed', 10, 18), 187 | (20, 'init.txt breaks down after startup', 'fixed', 4, 10), 188 | (21, 'compile.png breaks down after startup', 'clear', 7, 9), 189 | (22, 'Unreachable code in index.net stops compilation flow', 'fixed', 16, 9), 190 | (23, 'Inappropriate prompt from index.net', 'closed', 18, 1), 191 | (24, 'Implement documentation for index.intro module', 'closed', 9, 11), 192 | (25, 'Invalid welcoming message in file.sick', 'clear', 20, 5), 193 | (26, 'Unreachable code in Login.html stops compilation flow', 'fixed', 27, 1), 194 | (27, 'Hotfix for security issue in View.dd introduces new security issue', 'clear', 30, 6), 195 | (28, 'Hotfix for security issue in Jason.exe introduces new security issue', 'closed', 15, 2), 196 | (29, 'Loose Cohesion and Strong Coupling in READ.img', 'fixed', 13, 8), 197 | (30, 'Inappropriate prompt from config.dd', 'fixed', 29, 12), 198 | (31, 'Invalid welcoming message in Administrate.soshy', 'closed', 12, 10), 199 | (32, 'Hotfix for security issue in Index.class introduces new security issue', 'clear', 5, 16), 200 | (33, 'Loose Cohesion and Strong Coupling in Bean.php', 'clear', 19, 8), 201 | (34, 'Loose Cohesion and Strong Coupling in file.png', 'closed', 14, 16), 202 | (35, 'Invalid welcoming message in Accelerate.sick', 'clear', 17, 14), 203 | (36, 'Compilation failed while trying to execute index.intro', 'clear', 11, 19), 204 | (37, 'Security Flaw in Music.jpg inner code', 'closed', 11, 11), 205 | (38, 'index.db breaks down after startup', 'closed', 23, 8), 206 | (39, 'Unreachable code in Music.jpg stops compilation flow', 'clear', 5, 19), 207 | (40, 'Unimplemented exception thrown in Accelerate.sick', 'clear', 20, 1), 208 | (41, 'Invalid welcoming message in Search.py', 'clear', 32, 14), 209 | (42, 'Invalid welcoming message in index.cpp', 'clear', 26, 15), 210 | (43, 'Compilation failed while trying to execute index.db', 'clear', 15, 1), 211 | (44, 'Root.net breaks down after startup', 'fixed', 31, 5), 212 | (45, 'Unimplemented exception thrown in init.txt', 'clear', 30, 2), 213 | (46, 'Critical bug in compile.html ruins application when executed', 'opened', 3, 11), 214 | (47, 'Inappropriate prompt from index.db', 'clear', 30, 14), 215 | (48, 'Implement documentation for file.cpp module', 'opened', 12, 14), 216 | (49, 'Inappropriate prompt from Register.py', 'fixed', 9, 2), 217 | (50, 'Implement documentation for index.db module', 'fixed', 17, 7), 218 | (51, 'Critical bug in Trade.idk ruins application when executed', 'clear', 27, 13), 219 | (52, 'Unimplemented exception thrown in Beat.xix', 'fixed', 16, 6), 220 | (53, 'Unimplemented exception thrown in Administrate.go', 'clear', 1, 17), 221 | (54, 'Unimplemented exception thrown in Login.html', 'clear', 32, 1), 222 | (55, 'Unreachable code in Register.py stops compilation flow', 'opened', 21, 18), 223 | (56, 'Hotfix for security issue in pipeline.dd introduces new security issue', 'fixed', 27, 17), 224 | (57, 'Invalid welcoming message in init.txt', 'fixed', 14, 15), 225 | (58, 'Implement documentation for Administrate.soshy module', 'opened', 28, 1), 226 | (59, 'Hotfix for security issue in index.soshy introduces new security issue', 'closed', 11, 3), 227 | (60, 'Implement documentation for file.sick module', 'closed', 31, 10), 228 | (61, 'Loose Cohesion and Strong Coupling in Root.net', 'closed', 13, 7), 229 | (62, 'Compilation failed while trying to execute index.net', 'opened', 8, 19), 230 | (63, 'Unimplemented exception thrown in Register.py', 'clear', 21, 19), 231 | (64, 'file.sick breaks down after startup', 'closed', 35, 19), 232 | (65, 'Security Flaw in pipeline.dd inner code', 'opened', 3, 19), 233 | (66, 'Invalid welcoming message in index.intro', 'closed', 8, 6), 234 | (67, 'Security Flaw in Beat.xix inner code', 'opened', 33, 7), 235 | (68, 'Inappropriate prompt from compile.ivory', 'clear', 11, 4), 236 | (69, 'Inappropriate prompt from Search.py', 'clear', 12, 17), 237 | (70, 'Hotfix for security issue in Login.db introduces new security issue', 'clear', 2, 19), 238 | (71, 'Implement documentation for Index.class module', 'closed', 32, 3), 239 | (72, 'Loose Cohesion and Strong Coupling in index.soshy', 'opened', 29, 12), 240 | (73, 'Loose Cohesion and Strong Coupling in Beat.html', 'opened', 2, 15), 241 | (74, 'Compilation failed while trying to execute init.xml', 'opened', 24, 12), 242 | (75, 'Critical bug in Controller.php ruins application when executed', 'fixed', 8, 16); 243 | 244 | INSERT INTO commits(id, message, issue_id, repository_id, contributor_id) 245 | VALUES 246 | (1, 'Deleted deprecated functionality from index.cpp', 58, 17, 8), 247 | (2, 'Created README.MD', 15, 14, 8), 248 | (3, 'Initial Commit', 52, 24, 1), 249 | (4, 'Implemented config.json functionality', 15, 10, 12), 250 | (5, 'Deleted deprecated functionality from index.dd', 32, 13, 18), 251 | (6, 'Hotfix for bug in Index.class', 71, 19, 1), 252 | (7, 'Patch Index.javav.', 38, 8, 11), 253 | (8, 'Deleted deprecated functionality from Operate.xix', NULL, 28, 9), 254 | (9, 'Fixed security issue in file.png', NULL, 6, 2), 255 | (10, 'Deleted deprecated functionality from index.net', NULL, 27, 1), 256 | (11, 'Patch Model.MDv.', 52, 7, 16), 257 | (12, 'Deleted deprecated functionality from Music.jpg', 41, 6, 11), 258 | (13, 'Implemented index.net functionality', NULL, 15, 11), 259 | (14, 'Fixed index.dd', 40, 1, 7), 260 | (15, 'Fixed index.soshy', NULL, 19, 1), 261 | (16, 'Patch Operate.xixv.', NULL, 21, 4), 262 | (17, 'Hotfix for bug in Database.dd', 73, 14, 11), 263 | (18, 'Hotfix for bug in init.xml', 3, 10, 11), 264 | (19, 'Hotfix for bug in compile.png', 2, 7, 3), 265 | (20, 'Fixed init.xml', 15, 30, 15), 266 | (21, 'Hotfix for bug in Administrate.soshy', 8, 26, 19), 267 | (22, 'Implemented Index.class functionality', NULL, 14, 13), 268 | (23, 'Fixed security issue in Beat.bat', NULL, 7, 4), 269 | (24, 'Patch index.netv.', 36, 16, 14), 270 | (25, 'Implemented compile.png functionality', 21, 10, 2), 271 | (26, 'Fixed security issue in compile.html', 72, 22, 4), 272 | (27, 'Patch index.ddv.', 62, 6, 3), 273 | (28, 'Fixed Controller.php', 4, 9, 7), 274 | (29, 'Patch Find.javav.', 29, 28, 4), 275 | (30, 'Hotfix for bug in compile.ivory', 43, 25, 14), 276 | (31, 'Fixed security issue in compile.png', 64, 16, 10), 277 | (32, 'Implemented Beat.bat functionality', NULL, 5, 18), 278 | (33, 'Patch Database.ddv.', 17, 4, 15), 279 | (34, 'Deleted deprecated functionality from Model.MD', 48, 17, 7), 280 | (35, 'Patch init.txtv.', 51, 11, 2), 281 | (36, 'Fixed menu.net', 48, 3, 18), 282 | (37, 'Implemented Find.java functionality', NULL, 1, 1), 283 | (38, 'Deleted deprecated functionality from index.intro', 70, 18, 16), 284 | (39, 'Implemented Beat.html functionality', 51, 1, 5), 285 | (40, 'Deleted deprecated functionality from Database.dd', NULL, 2, 13), 286 | (41, 'Implemented Trade.idk functionality', NULL, 15, 19), 287 | (42, 'Hotfix for bug in compile.html', 15, 6, 19), 288 | (43, 'Fixed security issue in Search.py', 17, 21, 15), 289 | (44, 'Fixed security issue in Accelerate.sick', 20, 2, 17), 290 | (45, 'Fixed security issue in Administrate.soshy', 58, 25, 1), 291 | (46, 'Fixed security issue in file.txt', NULL, 1, 14), 292 | (47, 'Fixed Operate.xix', 29, 27, 15), 293 | (48, 'Implemented init.xml functionality', 39, 7, 17), 294 | (49, 'Fixed config.json', 1, 28, 5), 295 | (50, 'Implemented Database.dd functionality', NULL, 29, 8); 296 | 297 | INSERT INTO files(id, name, size, parent_id, commit_id) 298 | VALUES 299 | (1, 'Trade.idk', 2598.0, 1, 1), 300 | (2, 'menu.net', 9238.31, 2, 2), 301 | (3, 'Administrate.soshy', 1246.93, 3, 3), 302 | (4, 'Controller.php', 7353.15, 4, 4), 303 | (5, 'Find.java', 9957.86, 5, 5), 304 | (6, 'Controller.json', 14034.87, 3, 6), 305 | (7, 'Operate.xix', 7662.92, 7, 7), 306 | (8, 'file.sick', 10548.35, 8, 8), 307 | (9, 'config.dd', 8745.77, 9, 9), 308 | (10, 'Index.java', 6121.35, 10, 10), 309 | (11, 'compile.ivory', 1185.04, 11, 1), 310 | (12, 'Model.MD', 4753.67, 3, 12), 311 | (13, 'Beat.html', 907.3, 13, 13), 312 | (14, 'READ.img', 2627.6, 14, 7), 313 | (15, 'Search.py', 8831.43, 15, 15), 314 | (16, 'Controller.intro', 27302.85, 11, 1), 315 | (17, 'Login.html', 2863.23, 16, 17), 316 | (18, 'Administrate.go', 24612.57, 9, 18), 317 | (19, 'READ.html', 2396.47, 8, 1), 318 | (20, 'index.net', 9261.71, 20, 20), 319 | (21, 'Index.class', 4001.15, 21, 21), 320 | (22, 'config.json', 6049.09, 22, 22), 321 | (23, 'pipeline.dd', 18407.72, NULL, 19), 322 | (24, 'Accelerate.dd', 23042.88, 24, 19), 323 | (25, 'Database.dd', 14905.56, NULL, 25), 324 | (26, 'Login.db', 8015.83, NULL, 21), 325 | (27, 'Beat.bat', 21431.98, 25, 12), 326 | (28, 'Jason.txt', 10317.54, NULL, 28), 327 | (29, 'Jason.exe', 28209.18, 8, 25), 328 | (30, 'Accelerate.idk', 5520.3, 30, 1), 329 | (31, 'file.txt', 5514.02, 27, 1), 330 | (32, 'Music.jpg', 917.75, 1, 3), 331 | (33, 'Root.net', 6784.97, 8, 28), 332 | (34, 'sound.sick', 8749.82, 20, 16), 333 | (35, 'index.dd', 35942.21, NULL, 35), 334 | (36, 'index.intro', 14325.29, 26, 36), 335 | (37, 'init.xml', 40028.01, NULL, 22), 336 | (38, 'file.cpp', 3038.23, NULL, 22), 337 | (39, 'Beat.xix', 5877.21, 22, 31), 338 | (40, 'index.cpp', 28912.18, 2, 40), 339 | (41, 'compile.png', 20510.09, 22, 24), 340 | (42, 'Register.py', 2037.26, 5, 27), 341 | (43, 'init.txt', 16089.79, 28, 4), 342 | (44, 'View.dd', 2470.36, NULL, 44), 343 | (45, 'file.png', 7755.49, NULL, 23), 344 | (46, 'index.db', 3821.36, 11, 46), 345 | (47, 'Accelerate.sick', 5774.32, 47, 47), 346 | (48, 'index.soshy', 30522.96, 30, 26), 347 | (49, 'compile.html', 27402.59, 28, 24), 348 | (50, 'Bean.php', 4184.45, 20, 35); 349 | 350 | UPDATE files 351 | SET parent_id = 42 352 | WHERE id = 5; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Database Basics – MySQL 2 | 3 | [**Database Basics** course at SoftUni with MySQL - Jan 2018](https://softuni.bg/trainings/1871/database-basics-mysql-january-2018) 4 | --------------------------------------------------------------------------------