├── 012_Exporting_Data.sql ├── 015_Some_Test_Data.sql ├── 020_Solutions1.sql ├── 035_Solutions2.sql ├── 040_Health_Database.sql ├── 044_Solutions3.sql ├── 046_Foreign_Keys.sql ├── 048_Joins_and_Cartesian_Products.sql ├── 049_Inner_Joins.sql ├── 050_Left_and_Right_Outer_Joins.sql ├── 051_Joins_Between_Pairs_of_Tables.sql ├── 054_Many_to_Many.sql ├── 055_Joining_Tables_to_Themselves.sql ├── 056_Restrict.sql ├── 059_Online_Shop.sql ├── 063_Adding_Columns.sql ├── 064_Adding_Foreign_keys.sql ├── 065_Adding_Indexes.sql ├── 066_Indexing_Multiple_Columns.sql ├── 069_Views.sql ├── 070_View_Algorithms.sql ├── 071_With_Check_Option.sql ├── 074_Using_Variables.sql ├── 075_Setting_Variables_With_Selects.sql ├── 076_Select_Update_Example.sql ├── 077_Fixing_Select_Update_With_Table_Locks.sql ├── 079_A_Simple_Transaction.sql ├── 082_Demonstrating_Isolation_Levels_and_Row_Locking.sql ├── 087_Select_for_Update.sql ├── 088_Lock_in_Share_Mode.sql ├── 089_String_functions.sql ├── 090_Date_Functions.sql ├── 091_Control_Flow_Functions.sql ├── 092_Casting.sql ├── 099_Hello_World.sql ├── 100_Setting_the_Definer.sql ├── 101_Procedure_Permission_Example.sql ├── 102_Procedure_Permissions.sql ├── 103_Passing_Parameters.sql ├── 106_Out_Parameters.sql ├── 108_If.sql ├── 109_Local_Variables.sql ├── 110_Account_Withdrawal.sql ├── 111_Transactional_Withdrawal.sql ├── 113_Error_Handlers.sql ├── 114_While_Loops.sql ├── 115_Labelled_Loops.sql ├── 116_Generating_Random_Data.sql ├── 117_A_Data_Generating_Procedure.sql ├── 118_Cursors.sql ├── 119_Fetching_Cursor_Data_With_Loops.sql ├── 120_Case_Expression.sql ├── 123_Solutions4.sql ├── 124_Introducing_Triggers.sql ├── 125_Triggers_and_Validation.sql ├── 126_Triggers_and_Transactions.sql ├── 127_Triggers_Exercise.txt ├── 128_Solution5.sql ├── 130_Defining_Functions.sql ├── 135_Art_Shop.sql ├── clean.sql ├── makefile └── out.png /012_Exporting_Data.sql: -------------------------------------------------------------------------------- 1 | -- MySQL dump 10.13 Distrib 5.6.24, for osx10.8 (x86_64) 2 | -- 3 | -- Host: 127.0.0.1 Database: tutorial1 4 | -- ------------------------------------------------------ 5 | -- Server version 5.6.27 6 | 7 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 8 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 9 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 10 | /*!40101 SET NAMES utf8 */; 11 | /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; 12 | /*!40103 SET TIME_ZONE='+00:00' */; 13 | /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; 14 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 15 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 16 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; 17 | 18 | -- 19 | -- Table structure for table `users` 20 | -- 21 | 22 | DROP DATABASE IF EXISTS CAVE_TEST; 23 | CREATE DATABASE IF NOT EXISTS CAVE_TEST; 24 | USE CAVE_TEST; 25 | 26 | DROP TABLE IF EXISTS `users`; 27 | /*!40101 SET @saved_cs_client = @@character_set_client */; 28 | /*!40101 SET character_set_client = utf8 */; 29 | CREATE TABLE `users` ( 30 | `id` int(11) NOT NULL AUTO_INCREMENT, 31 | `name` text, 32 | PRIMARY KEY (`id`) 33 | ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1; 34 | /*!40101 SET character_set_client = @saved_cs_client */; 35 | 36 | -- 37 | -- Dumping data for table `users` 38 | -- 39 | 40 | LOCK TABLES `users` WRITE; 41 | /*!40000 ALTER TABLE `users` DISABLE KEYS */; 42 | INSERT INTO `users` VALUES (1,'Bob'),(5,'Vicky'),(6,'Sue'),(7,'Rich'),(8,'Raj'); 43 | /*!40000 ALTER TABLE `users` ENABLE KEYS */; 44 | UNLOCK TABLES; 45 | /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; 46 | 47 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; 48 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; 49 | /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; 50 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 51 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 52 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 53 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; 54 | 55 | -- Dump completed on 2015-10-09 18:09:02 56 | -------------------------------------------------------------------------------- /015_Some_Test_Data.sql: -------------------------------------------------------------------------------- 1 | -- MySQL dump 10.13 Distrib 5.6.24, for osx10.8 (x86_64) 2 | -- 3 | -- Host: 127.0.0.1 Database: tutorial1 4 | -- ------------------------------------------------------ 5 | -- Server version 5.6.27 6 | 7 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 8 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 9 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 10 | /*!40101 SET NAMES utf8 */; 11 | /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; 12 | /*!40103 SET TIME_ZONE='+00:00' */; 13 | /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; 14 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 15 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 16 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; 17 | 18 | -- 19 | -- Table structure for table `users` 20 | -- 21 | 22 | DROP DATABASE IF EXISTS CAVE_TEST; 23 | CREATE DATABASE IF NOT EXISTS CAVE_TEST; 24 | USE CAVE_TEST; 25 | 26 | DROP TABLE IF EXISTS `users`; 27 | /*!40101 SET @saved_cs_client = @@character_set_client */; 28 | /*!40101 SET character_set_client = utf8 */; 29 | CREATE TABLE `users` ( 30 | `id` int(11) NOT NULL AUTO_INCREMENT, 31 | `name` text, 32 | `age` int(11) DEFAULT NULL, 33 | PRIMARY KEY (`id`) 34 | ) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=latin1; 35 | /*!40101 SET character_set_client = @saved_cs_client */; 36 | 37 | -- 38 | -- Dumping data for table `users` 39 | -- 40 | 41 | LOCK TABLES `users` WRITE; 42 | /*!40000 ALTER TABLE `users` DISABLE KEYS */; 43 | INSERT INTO `users` VALUES (1,'Bob',46),(2,'Bob',47),(3,'Vicky',25),(4,'Raj',21),(5,'Pete',60),(6,'John',41),(7,'Mark',30),(8,'Sue',53),(9,'Don',25),(10,'John',20),(11,'Syed',33),(12,'Christina',28),(13,'Mario',19),(14,'Justin',23),(15,'Clare',49),(16,'Sarah',73),(17,'Pete',28),(18,'Steve',32),(19,'Zoe',36),(20,'Cori',17),(21,NULL,99),(22,NULL,20); 44 | /*!40000 ALTER TABLE `users` ENABLE KEYS */; 45 | UNLOCK TABLES; 46 | /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; 47 | 48 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; 49 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; 50 | /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; 51 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 52 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 53 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 54 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; 55 | 56 | -- Dump completed on 2015-10-12 17:15:26 57 | -------------------------------------------------------------------------------- /020_Solutions1.sql: -------------------------------------------------------------------------------- 1 | USE CAVE_TEST; 2 | 3 | -- 1. Select all the rows where age is greater than 20 but less than 30 4 | select * from users where age > 20 and age < 30; 5 | 6 | 7 | -- 2. Select all rows where age is between 20 (inclusive) and 30 (inclusive) 8 | select * from users where age >= 20 and age <= 30; 9 | 10 | 11 | -- 3. Select all rows where age is between 20 (inclusive) and 30 (inclusive) and the name is not “Vicky” 12 | select * from users where (age >= 20 and age <= 30) and not name = "Vicky"; 13 | 14 | -- 4. Select all rows where either the name is null or the name does not contain the letter “e” 15 | select * from users where (name not like '%e%') or (name is null); 16 | 17 | 18 | -- 5. Select all rows for users aged between 30 and 40 whether the name contains either the letter “o” or “e” 19 | select * from users where (age > 30 and age < 40) and (name like '%o%' or name like '%e%'); 20 | 21 | 22 | -- 6. Select all rows where either the name contains an “o” or the id is less than 5, but not both 23 | select * from users where name like '%o%' xor id < 5; 24 | -------------------------------------------------------------------------------- /035_Solutions2.sql: -------------------------------------------------------------------------------- 1 | -- Create the following tables in MySQL 2 | 3 | -- Products 4 | 5 | -- primary key 6 | -- name 7 | -- category 8 | -- sell by date 9 | -- sold or not 10 | -- moment of sale 11 | -- quantity 12 | -- weight Kg 13 | 14 | use CAVE_TEST; 15 | 16 | create table products(id int primary key auto_increment, name varchar(40), category enum('Baked Goods', 'Fruit and Veg', 'Dairy'), 17 | sell_by date, sold bool, moment_of_sale timestamp, quantity int, weight numeric(6,3)); 18 | 19 | select * from products; 20 | 21 | insert into products(name, category, sell_by, sold, moment_of_sale, quantity, weight) values 22 | ("Sack of Potatoes", "Fruit and Veg", "2016-10-14", true, "2015-11-01 10:23:45", 30, 10); 23 | 24 | -- --------------------------------------- 25 | -- Personnel 26 | 27 | -- primary key 28 | -- given name 29 | -- family name 30 | -- gender 31 | -- telephone number 32 | -- marital status 33 | -- age 34 | -- salary 35 | -- position 36 | -- date started 37 | 38 | -- --------------------------------------- 39 | 40 | create table personnel(id int primary key auto_increment, given_name varchar(50), family_name varchar(50), gender enum('MALE', 'FEMALE'), 41 | telephone varchar(100), married bool, age tinyint, salary int, position enum('developer', 'manager', 'CEO'), date_started date); 42 | 43 | insert into personnel(given_name, family_name, gender, telephone, married, age, salary, position, date_started) values 44 | ("Arnold", "Brown", "MALE", "01348908340", true, 34, 34000, 'developer', "2014-05-06"); 45 | 46 | 47 | select * from personnel; 48 | 49 | -- Address 50 | 51 | -- First line 52 | -- Second line 53 | -- City 54 | -- Region 55 | -- zip/postal code 56 | -- Two letter country code 57 | 58 | create table address(id int primary key auto_increment, first_line varchar(60), second_line varchar(60), 59 | city varchar(60), region varchar(60), postal_code char(7), country_code char(2)); 60 | 61 | insert into address(first_line, second_line, city, region, postal_code, country_code) values 62 | ("The Badger Inn", "23 Church Lane", "Badgerton", "East Badgering", "BA4DER", "UK"); 63 | 64 | select * from address; 65 | -------------------------------------------------------------------------------- /040_Health_Database.sql: -------------------------------------------------------------------------------- 1 | -- MySQL dump 10.13 Distrib 5.6.14, for osx10.7 (x86_64) 2 | -- 3 | -- Host: localhost Database: health 4 | -- ------------------------------------------------------ 5 | -- Server version 5.6.14 6 | 7 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 8 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 9 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 10 | /*!40101 SET NAMES utf8 */; 11 | /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; 12 | /*!40103 SET TIME_ZONE='+00:00' */; 13 | /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; 14 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 15 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 16 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; 17 | 18 | DROP DATABASE IF EXISTS CAVE_HEALTH_SURVEY; 19 | CREATE DATABASE IF NOT EXISTS CAVE_HEALTH_SURVEY; 20 | USE CAVE_HEALTH_SURVEY; 21 | 22 | -- 23 | -- Table structure for table `concentration` 24 | -- 25 | 26 | DROP TABLE IF EXISTS `concentration`; 27 | /*!40101 SET @saved_cs_client = @@character_set_client */; 28 | /*!40101 SET character_set_client = utf8 */; 29 | CREATE TABLE `concentration` ( 30 | `id` tinyint(4) NOT NULL AUTO_INCREMENT, 31 | `question` varchar(120) DEFAULT NULL, 32 | PRIMARY KEY (`id`) 33 | ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1; 34 | /*!40101 SET character_set_client = @saved_cs_client */; 35 | 36 | -- 37 | -- Dumping data for table `concentration` 38 | -- 39 | 40 | LOCK TABLES `concentration` WRITE; 41 | /*!40000 ALTER TABLE `concentration` DISABLE KEYS */; 42 | INSERT INTO `concentration` VALUES (1,'Very poor; I am easily distracted or have trouble thinking clearly.'),(2,'Not very good, but I can concentrate when really necessary.'),(3,'My ability to concentrate is around average.'),(4,'I can concentrate rather well.'),(5,'I have very good concentration and focus.'); 43 | /*!40000 ALTER TABLE `concentration` ENABLE KEYS */; 44 | UNLOCK TABLES; 45 | 46 | -- 47 | -- Table structure for table `drink` 48 | -- 49 | 50 | DROP TABLE IF EXISTS `drink`; 51 | /*!40101 SET @saved_cs_client = @@character_set_client */; 52 | /*!40101 SET character_set_client = utf8 */; 53 | CREATE TABLE `drink` ( 54 | `id` tinyint(4) NOT NULL AUTO_INCREMENT, 55 | `question` varchar(120) DEFAULT NULL, 56 | PRIMARY KEY (`id`) 57 | ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1; 58 | /*!40101 SET character_set_client = @saved_cs_client */; 59 | 60 | -- 61 | -- Dumping data for table `drink` 62 | -- 63 | 64 | LOCK TABLES `drink` WRITE; 65 | /*!40000 ALTER TABLE `drink` DISABLE KEYS */; 66 | INSERT INTO `drink` VALUES (1,'I don\'t drink alcohol'),(2,'Occasionally'),(3,'I drink every day, but moderately'),(4,'I\'m a heavy drinker'); 67 | /*!40000 ALTER TABLE `drink` ENABLE KEYS */; 68 | UNLOCK TABLES; 69 | 70 | -- 71 | -- Table structure for table `exercise` 72 | -- 73 | 74 | DROP TABLE IF EXISTS `exercise`; 75 | /*!40101 SET @saved_cs_client = @@character_set_client */; 76 | /*!40101 SET character_set_client = utf8 */; 77 | CREATE TABLE `exercise` ( 78 | `id` tinyint(4) NOT NULL AUTO_INCREMENT, 79 | `question` varchar(120) DEFAULT NULL, 80 | PRIMARY KEY (`id`) 81 | ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1; 82 | /*!40101 SET character_set_client = @saved_cs_client */; 83 | 84 | -- 85 | -- Dumping data for table `exercise` 86 | -- 87 | 88 | LOCK TABLES `exercise` WRITE; 89 | /*!40000 ALTER TABLE `exercise` DISABLE KEYS */; 90 | INSERT INTO `exercise` VALUES (1,'I avoid exercise'),(2,'Sometimes / Occasionally'),(3,'I exercise at least weekly'),(4,'I exercise daily'); 91 | /*!40000 ALTER TABLE `exercise` ENABLE KEYS */; 92 | UNLOCK TABLES; 93 | 94 | -- 95 | -- Table structure for table `fat` 96 | -- 97 | 98 | DROP TABLE IF EXISTS `fat`; 99 | /*!40101 SET @saved_cs_client = @@character_set_client */; 100 | /*!40101 SET character_set_client = utf8 */; 101 | CREATE TABLE `fat` ( 102 | `id` tinyint(4) NOT NULL AUTO_INCREMENT, 103 | `question` varchar(120) DEFAULT NULL, 104 | PRIMARY KEY (`id`) 105 | ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1; 106 | /*!40101 SET character_set_client = @saved_cs_client */; 107 | 108 | -- 109 | -- Dumping data for table `fat` 110 | -- 111 | 112 | LOCK TABLES `fat` WRITE; 113 | /*!40000 ALTER TABLE `fat` DISABLE KEYS */; 114 | INSERT INTO `fat` VALUES (1,'I follow a low-fat diet.'),(2,'I try to avoid fat, but my diet isn\'t really low fat.'),(3,'I think I eat an average amount of fat.'),(4,'I probably eat more fat than average.'),(5,'I eat a high-fat diet and consume a much greater proportion of my calories from fat than the average person.'); 115 | /*!40000 ALTER TABLE `fat` ENABLE KEYS */; 116 | UNLOCK TABLES; 117 | 118 | -- 119 | -- Table structure for table `health` 120 | -- 121 | 122 | DROP TABLE IF EXISTS `health`; 123 | /*!40101 SET @saved_cs_client = @@character_set_client */; 124 | /*!40101 SET character_set_client = utf8 */; 125 | CREATE TABLE `health` ( 126 | `id` tinyint(4) NOT NULL AUTO_INCREMENT, 127 | `question` varchar(120) DEFAULT NULL, 128 | PRIMARY KEY (`id`) 129 | ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1; 130 | /*!40101 SET character_set_client = @saved_cs_client */; 131 | 132 | -- 133 | -- Dumping data for table `health` 134 | -- 135 | 136 | LOCK TABLES `health` WRITE; 137 | /*!40000 ALTER TABLE `health` DISABLE KEYS */; 138 | INSERT INTO `health` VALUES (1,'I have suffered, or am suffering from, a serious illness during the past year'),(2,'My health has been poor, but I haven\'t been seriously ill.'),(3,'My health has been OK.'),(4,'My health has generally been good.'),(5,'My health has been excellent.'); 139 | /*!40000 ALTER TABLE `health` ENABLE KEYS */; 140 | UNLOCK TABLES; 141 | 142 | -- 143 | -- Table structure for table `smoke` 144 | -- 145 | 146 | DROP TABLE IF EXISTS `smoke`; 147 | /*!40101 SET @saved_cs_client = @@character_set_client */; 148 | /*!40101 SET character_set_client = utf8 */; 149 | CREATE TABLE `smoke` ( 150 | `id` tinyint(4) NOT NULL AUTO_INCREMENT, 151 | `question` varchar(120) DEFAULT NULL, 152 | PRIMARY KEY (`id`) 153 | ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1; 154 | /*!40101 SET character_set_client = @saved_cs_client */; 155 | 156 | -- 157 | -- Dumping data for table `smoke` 158 | -- 159 | 160 | LOCK TABLES `smoke` WRITE; 161 | /*!40000 ALTER TABLE `smoke` DISABLE KEYS */; 162 | INSERT INTO `smoke` VALUES (1,'I don\'t smoke'),(2,'Occasionally'),(3,'I smoke daily, but moderately'),(4,'I smoke heavily'); 163 | /*!40000 ALTER TABLE `smoke` ENABLE KEYS */; 164 | UNLOCK TABLES; 165 | 166 | -- 167 | -- Table structure for table `sugar` 168 | -- 169 | 170 | DROP TABLE IF EXISTS `sugar`; 171 | /*!40101 SET @saved_cs_client = @@character_set_client */; 172 | /*!40101 SET character_set_client = utf8 */; 173 | CREATE TABLE `sugar` ( 174 | `id` tinyint(4) NOT NULL AUTO_INCREMENT, 175 | `question` varchar(120) DEFAULT NULL, 176 | PRIMARY KEY (`id`) 177 | ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1; 178 | /*!40101 SET character_set_client = @saved_cs_client */; 179 | 180 | -- 181 | -- Dumping data for table `sugar` 182 | -- 183 | 184 | LOCK TABLES `sugar` WRITE; 185 | /*!40000 ALTER TABLE `sugar` DISABLE KEYS */; 186 | INSERT INTO `sugar` VALUES (1,'Very rarely or never'),(2,'Occasionally'),(3,'Don\'t know / uncertain'),(4,'Often/frequently'),(5,'I am addicted to sweet things / Very often'); 187 | /*!40000 ALTER TABLE `sugar` ENABLE KEYS */; 188 | UNLOCK TABLES; 189 | 190 | -- 191 | -- Table structure for table `survey` 192 | -- 193 | 194 | DROP TABLE IF EXISTS `survey`; 195 | /*!40101 SET @saved_cs_client = @@character_set_client */; 196 | /*!40101 SET character_set_client = utf8 */; 197 | CREATE TABLE `survey` ( 198 | `id` int(11) NOT NULL AUTO_INCREMENT, 199 | `gender` enum('male','female') NOT NULL, 200 | `country` varchar(30) NOT NULL, 201 | `weight` decimal(3,0) NOT NULL, 202 | `height` decimal(3,0) NOT NULL, 203 | `age` decimal(3,0) NOT NULL, 204 | `fat` tinyint(4) NOT NULL, 205 | `sugar` tinyint(4) NOT NULL, 206 | `smoke` tinyint(4) NOT NULL, 207 | `drink` tinyint(4) NOT NULL, 208 | `exercise` tinyint(4) NOT NULL, 209 | `health` tinyint(4) NOT NULL, 210 | `concentration` tinyint(4) NOT NULL, 211 | PRIMARY KEY (`id`), 212 | KEY `fat` (`fat`), 213 | KEY `sugar` (`sugar`), 214 | KEY `smoke` (`smoke`), 215 | KEY `drink` (`drink`), 216 | KEY `exercise` (`exercise`), 217 | KEY `health` (`health`), 218 | KEY `concentration` (`concentration`), 219 | CONSTRAINT `survey_ibfk_1` FOREIGN KEY (`fat`) REFERENCES `fat` (`id`), 220 | CONSTRAINT `survey_ibfk_2` FOREIGN KEY (`sugar`) REFERENCES `sugar` (`id`), 221 | CONSTRAINT `survey_ibfk_3` FOREIGN KEY (`smoke`) REFERENCES `smoke` (`id`), 222 | CONSTRAINT `survey_ibfk_4` FOREIGN KEY (`drink`) REFERENCES `drink` (`id`), 223 | CONSTRAINT `survey_ibfk_5` FOREIGN KEY (`exercise`) REFERENCES `exercise` (`id`), 224 | CONSTRAINT `survey_ibfk_6` FOREIGN KEY (`health`) REFERENCES `health` (`id`), 225 | CONSTRAINT `survey_ibfk_7` FOREIGN KEY (`concentration`) REFERENCES `concentration` (`id`) 226 | ) ENGINE=InnoDB AUTO_INCREMENT=150 DEFAULT CHARSET=latin1; 227 | /*!40101 SET character_set_client = @saved_cs_client */; 228 | 229 | -- 230 | -- Dumping data for table `survey` 231 | -- 232 | 233 | LOCK TABLES `survey` WRITE; 234 | /*!40000 ALTER TABLE `survey` DISABLE KEYS */; 235 | INSERT INTO `survey` VALUES (1,'male','UK',74,182,41,3,2,1,2,2,4,4),(2,'male','Kosova',73,183,26,4,4,1,1,2,5,3),(3,'male','India',80,165,25,2,2,1,2,2,4,3),(4,'male','USA',65,176,37,3,2,1,3,3,4,2),(5,'male','USA',73,183,19,1,1,1,2,3,5,5),(6,'male','Sweden',94,185,25,3,2,1,2,2,5,3),(7,'male','Argentina',68,178,28,2,1,1,2,4,5,4),(8,'male','USA',88,173,41,2,2,1,2,2,3,2),(9,'male','USA',51,172,16,3,3,1,1,2,4,3),(10,'male','Pakistan',77,182,19,3,4,1,1,4,4,2),(11,'male','China',80,175,26,3,3,1,1,2,3,3),(12,'male','Australia',89,186,22,2,2,1,1,4,5,4),(13,'female','Hungary',46,169,23,1,2,1,1,2,3,2),(14,'male','Syria',70,180,30,2,4,1,1,3,4,4),(15,'male','India',95,160,27,4,5,4,4,3,2,4),(16,'male','Poland',60,173,28,3,4,1,2,2,4,4),(17,'female','UK',70,165,32,4,4,1,2,4,3,3),(18,'male','Ireland',73,166,32,4,5,1,2,2,3,2),(19,'male','India',62,162,23,1,4,1,2,4,4,2),(20,'male','Greece',68,170,39,4,1,1,1,4,2,2),(21,'male','USA',130,185,46,4,4,1,2,2,3,2),(22,'male','ireland',62,172,21,3,4,1,2,3,5,4),(23,'male','USA',50,160,18,3,4,1,1,3,4,2),(24,'female','India',56,166,25,3,4,1,1,2,4,3),(25,'male','Croatia',111,198,29,4,2,3,1,3,4,2),(26,'male','Spain',54,180,15,3,2,1,1,2,4,4),(27,'male','USA',63,180,19,3,4,1,2,3,4,4),(28,'female','India',78,165,24,2,4,1,1,1,2,2),(29,'male','Poland',78,183,19,3,2,1,2,3,4,5),(30,'male','Nigeria',70,168,28,3,4,1,1,4,4,4),(31,'male','Indonesia',80,191,22,3,2,1,1,3,4,3),(32,'male','India',78,170,19,2,3,1,1,4,2,4),(33,'male','Hungary',95,180,41,3,2,1,2,3,4,5),(34,'male','USA',63,198,17,3,2,1,1,2,5,3),(35,'male','Lebanon',80,176,21,4,4,1,1,3,1,5),(36,'male','USA',120,140,14,3,4,1,1,2,4,3),(37,'male','India',75,182,24,3,2,1,1,3,4,3),(38,'male','USA',38,158,20,3,2,1,1,1,5,4),(39,'male','Canada',88,181,28,3,2,1,2,3,5,4),(40,'male','India',74,185,21,3,4,1,2,1,5,4),(41,'male','Italy',76,181,37,2,2,1,1,3,4,4),(42,'female','India',55,165,22,3,2,1,1,4,4,4),(43,'male','UK',83,185,55,5,1,2,2,3,5,4),(44,'male','Singapore',78,171,37,2,2,1,2,3,5,2),(45,'male','india',76,179,29,3,2,1,1,2,1,3),(46,'male','UK',66,182,49,1,2,1,2,4,3,3),(47,'male','India',76,180,23,3,2,1,1,1,4,4),(48,'male','India',83,186,21,3,4,1,1,2,2,3),(49,'male','Oman',74,164,35,1,1,1,1,3,1,2),(50,'male','USA',115,180,67,3,4,1,3,3,3,4),(51,'male','France',57,173,26,2,2,1,2,3,3,3),(52,'male','USA',80,171,50,2,2,1,3,2,4,2),(53,'male','Ukraine',65,170,29,4,4,1,1,3,3,3),(54,'male','USA',86,161,22,3,2,1,2,3,4,4),(55,'male','UK',86,181,41,5,2,1,2,2,4,3),(56,'male','USA',78,180,36,4,2,1,2,2,3,2),(57,'female','USA',68,168,43,3,2,1,2,3,4,4),(58,'male','India',65,183,20,3,2,1,1,2,2,1),(59,'female','Hungary',71,174,30,3,2,1,2,3,1,3),(60,'male','Syria',62,182,25,3,4,3,1,2,4,3),(61,'male','USA',70,178,33,3,4,1,3,3,4,4),(62,'male','USA',57,180,23,3,4,1,2,3,4,5),(63,'female','uk',72,167,50,2,2,1,2,1,4,4),(64,'male','UK',111,185,33,4,4,1,4,2,3,3),(65,'male','India',60,177,19,2,3,1,1,2,3,4),(66,'male','Sweden',92,171,27,3,4,1,2,2,4,4),(67,'male','USA',183,178,48,4,4,1,2,1,3,2),(68,'male','India',60,165,27,3,4,1,2,3,3,1),(69,'male','USA',91,183,30,3,4,1,2,3,4,3),(71,'female','USA',42,160,48,1,1,1,2,2,3,5),(72,'male','Slovakia',98,183,23,3,4,2,2,3,4,3),(73,'male','UK',82,185,25,3,5,1,1,2,2,2),(74,'male','Guatemala',90,176,36,2,2,1,1,3,3,3),(75,'male','USA',89,150,29,4,4,4,2,2,3,4),(76,'female','india',48,158,24,3,4,1,1,2,3,3),(77,'male','INDIA',53,172,23,1,4,3,2,1,4,3),(78,'male','Greece',100,180,28,3,3,2,2,2,3,2),(79,'male','Brazil',97,175,43,1,2,1,1,2,4,4),(80,'male','india',60,176,25,3,3,1,1,3,3,4),(81,'male','Pakistan',61,130,21,3,1,2,1,2,3,2),(82,'male','UK',90,168,43,2,3,1,2,4,5,4),(83,'female','USA',57,165,46,3,4,1,1,1,3,3),(84,'male','Switzerland',92,174,34,3,2,1,2,2,5,2),(85,'male','Nigeria',88,188,27,1,3,1,1,3,5,4),(86,'male','Nigeria',88,188,27,1,3,1,1,3,5,4),(87,'male','Ukraine',88,182,34,2,1,1,2,4,5,5),(88,'male','Ukraine',87,187,20,2,2,1,2,3,3,2),(89,'male','USA',60,167,19,2,4,1,1,2,5,4),(90,'male','india',75,176,22,3,4,1,2,4,3,3),(91,'male','pakistan',54,173,21,2,3,2,1,1,2,2),(92,'male','australia',78,180,36,3,2,1,2,2,3,4),(93,'male','india',67,167,23,2,2,1,2,3,3,3),(94,'male','Switzerland',71,180,23,2,2,1,1,3,4,3),(95,'male','India',63,165,22,3,4,1,1,2,3,3),(96,'female','UK',49,168,19,3,4,1,2,3,4,3),(97,'male','Slovenia',80,180,18,3,4,2,2,3,3,4),(98,'male','UK',65,176,16,4,4,1,2,4,5,4),(99,'male','india',71,172,50,3,2,1,1,4,1,3),(100,'male','Turkey',70,178,34,2,2,1,2,3,3,3),(101,'male','Nepal',70,175,27,3,2,2,2,2,3,3),(102,'male','Switzerland',78,175,58,2,4,4,2,3,3,4),(103,'male','UK',100,175,50,4,2,1,2,2,3,3),(104,'male','poland',100,180,32,3,3,1,2,4,4,4),(105,'male','Nepal',56,158,22,1,2,1,1,2,1,1),(106,'male','Poland',50,160,30,3,1,2,2,2,4,2),(107,'male','Russia',62,178,25,3,4,1,2,3,4,4),(108,'male','Greece',74,180,26,3,4,1,2,2,4,5),(109,'male','india',65,178,28,3,4,1,1,2,2,2),(110,'male','Uganda',90,180,51,3,2,2,2,2,3,4),(111,'male','Mexico',73,175,26,2,4,1,2,2,4,3),(112,'male','india',65,170,24,3,5,1,1,1,3,3),(113,'male','India',63,182,23,3,2,1,2,4,4,2),(114,'male','Greece',60,174,29,3,5,4,2,2,4,3),(115,'male','Belgium',85,183,37,3,2,1,2,3,3,2),(116,'male','USA',90,178,27,3,2,1,1,2,4,1),(117,'male','Norway',72,181,31,2,2,1,2,1,4,4),(118,'male','Canada',80,183,31,3,4,3,2,1,3,3),(119,'male','UK',71,172,40,2,4,1,1,2,2,3),(120,'male','Serbia',92,180,25,3,2,1,2,3,5,4),(121,'female','USA',73,157,46,3,2,1,2,3,3,1),(122,'male','Brazil',77,186,26,2,2,1,1,4,5,5),(123,'male','Canada',98,168,37,2,4,1,1,3,4,3),(124,'male','USA',198,198,35,1,2,1,2,2,5,5),(125,'male','USA',99,170,44,3,4,3,2,1,3,4),(126,'male','India',62,177,22,3,4,1,1,2,3,2),(127,'female','Philippines',62,123,22,2,2,1,1,2,4,3),(128,'female','sweden',69,167,47,5,2,1,2,2,3,3),(129,'male','Romania',87,191,21,4,5,1,2,2,4,3),(130,'male','Tanzania',70,185,21,3,2,2,2,2,4,3),(131,'male','Bosnia and Herzegowinia',100,195,25,1,2,2,1,3,2,4),(132,'male','Germany',67,172,26,1,2,1,2,4,4,3),(133,'male','india',78,164,34,2,3,1,1,2,3,3),(134,'male','india',62,168,32,2,4,1,1,2,3,4),(135,'male','india',85,171,29,3,4,1,1,2,4,3),(136,'male','South Africa',62,165,48,3,2,1,1,2,5,4),(137,'male','German',95,188,33,3,3,2,2,3,3,4),(138,'male','uk',89,183,68,1,1,1,2,4,5,4),(139,'male','Sweden',100,192,21,4,4,1,2,3,4,4),(140,'male','USA',81,180,25,3,2,1,2,4,4,3),(141,'male','Iran',73,176,19,3,2,1,1,1,3,2),(142,'male','Russia',78,183,30,3,4,1,2,2,3,3),(143,'male','canada',86,180,42,3,4,1,2,3,3,2),(144,'female','mexico',76,159,27,4,5,1,2,2,3,4),(145,'male','USA',136,170,23,3,3,1,1,3,2,3),(146,'male','India',88,172,23,3,4,1,1,2,3,2),(147,'male','UK',76,178,32,3,3,1,2,3,4,3),(148,'male','Philippines',80,176,34,3,3,3,2,3,4,5),(149,'male','USA',61,177,30,2,3,2,2,2,3,2); 236 | /*!40000 ALTER TABLE `survey` ENABLE KEYS */; 237 | UNLOCK TABLES; 238 | /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; 239 | 240 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; 241 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; 242 | /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; 243 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 244 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 245 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 246 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; 247 | 248 | -- Dump completed on 2015-11-06 15:30:29 249 | -------------------------------------------------------------------------------- /044_Solutions3.sql: -------------------------------------------------------------------------------- 1 | use CAVE_HEALTH_SURVEY; 2 | 3 | -- Won't work if sql_mode=only_full_group_by happens to be enabled. 4 | -- So disable it. 5 | SET sql_mode = ''; 6 | 7 | -- Answer using only one SQL query for each question. 8 | 9 | -- 10 | -- 1. Find out the average weight for each country. 11 | -- 12 | select country, avg(weight) from survey group by country; 13 | 14 | -- 15 | -- 2. Create a list of the number of respondents from each country. Order the list by the number of respondents. 16 | -- Show only those countries where the number of respondents was greater than 3. 17 | -- 18 | select count(*), country from survey group by country having count(*) > 3 order by count(*); 19 | 20 | -- 21 | -- 3. Display the average height for each country. Show also the number of respondents for each country and order the list by average height. 22 | -- 23 | 24 | select count(*), country, avg(height) from survey group by country order by avg(height); 25 | 26 | -- 27 | -- 4. For each country, find the average weight of both men and women in that country, and the number of respondents in each gender-country category. 28 | -- Display only those categories containing more than two respondents. Order the results by country. 29 | -- 30 | 31 | select gender, count(*), country, avg(weight) from survey group by country, gender having count(*) > 2 order by country ; 32 | 33 | -- 34 | -- 5. For each of the possible four answers to the exercise question, display the average health score for the respondents in that group. Order from poor health to good health. 35 | -- Is there any relationship between reported amount of exercise and reported state of health? If so, why? 36 | -- 37 | 38 | select exercise, avg(health) from survey group by exercise order by health 39 | -------------------------------------------------------------------------------- /046_Foreign_Keys.sql: -------------------------------------------------------------------------------- 1 | DROP DATABASE IF EXISTS CAVE_TEST; 2 | CREATE DATABASE CAVE_TEST; 3 | USE CAVE_TEST; 4 | 5 | create table address (id int primary key auto_increment, street varchar(50)); 6 | insert into address (street) values ('Apple Lane'), ('Broad Street'), ('Church Lane'); 7 | 8 | create table person(id int primary key auto_increment, name varchar(50), address_id int, foreign key (address_id) references address(id)); 9 | insert into person(name, address_id) values ('Anna', 1); 10 | insert into person(name, address_id) values ('Bob', 2); 11 | insert into person(name, address_id) values ('Clare', 3); 12 | 13 | -- This won't work: 14 | -- insert into person(name, address_id) values ('David', 4); 15 | 16 | -- But this will: 17 | insert into person(name, address_id) values ('Arnold', 1); 18 | -------------------------------------------------------------------------------- /048_Joins_and_Cartesian_Products.sql: -------------------------------------------------------------------------------- 1 | USE CAVE_TEST; 2 | 3 | select p.id as person_id, p.name, p.address_id as person_address_id, a.id as address_id, a.street from person p, address a 4 | where p.address_id=a.id 5 | -------------------------------------------------------------------------------- /049_Inner_Joins.sql: -------------------------------------------------------------------------------- 1 | use CAVE_TEST; 2 | 3 | select p.id as person_id, p.name, p.address_id as person_address_id, a.id as address_id, a.street from person p 4 | inner join address a on a.id=p.address_id 5 | -------------------------------------------------------------------------------- /050_Left_and_Right_Outer_Joins.sql: -------------------------------------------------------------------------------- 1 | USE CAVE_TEST; 2 | 3 | -- inner keyword is optional (has no effect) 4 | select name, street from person p inner join address a on p.address_id = a.id; 5 | 6 | -- outer keyword is optional (has no effect) 7 | select name, street from person p left outer join address a on p.address_id = a.id; 8 | 9 | -- outer keyword is optional (has no effect) 10 | select name, street from person p right outer join address a on p.address_id = a.id; 11 | -------------------------------------------------------------------------------- /051_Joins_Between_Pairs_of_Tables.sql: -------------------------------------------------------------------------------- 1 | use CAVE_HEALTH_SURVEY; 2 | 3 | select su.id, country, age, sm.question as smoking, e.question as exercise 4 | from survey su 5 | join smoke sm on su.smoke=sm.id 6 | join exercise e on su.exercise=e.id; 7 | -------------------------------------------------------------------------------- /054_Many_to_Many.sql: -------------------------------------------------------------------------------- 1 | use CAVE_TEST; 2 | 3 | create table product (id int primary key auto_increment, name varchar(50)); 4 | 5 | insert into product (name) values ('Electric cat groomer'), ('Automatic dog chaser'), ('Egg warmer'); 6 | 7 | create table person_product (person_id int not null, product_id int not null, foreign key (person_id) references person(id), foreign key (product_id) references product(id)); 8 | 9 | insert into person_product (person_id, product_id) values (1, 3), (4, 2), (1, 3), (1, 3), (2, 1), (3, 2); 10 | 11 | select p.name, pp.product_id, pr.name from person p 12 | join person_product pp on pp.person_id=p.id 13 | join product pr on pr.id=pp.product_id LIMIT 0, 1000; 14 | -------------------------------------------------------------------------------- /055_Joining_Tables_to_Themselves.sql: -------------------------------------------------------------------------------- 1 | DROP DATABASE IF EXISTS CAVE_TEST; 2 | CREATE DATABASE CAVE_TEST; 3 | USE CAVE_TEST; 4 | 5 | create table seats (id int primary key auto_increment, free bool); 6 | 7 | insert into seats (free) values (true), (false), (true), (true), (false), (true), (false), (true), (true), (false), (true); 8 | 9 | select s1.id as 'Seat One ID' from seats s1 join seats s2 on s1.id+1=s2.id where s1.free=true and s2.free=true; 10 | -------------------------------------------------------------------------------- /056_Restrict.sql: -------------------------------------------------------------------------------- 1 | DROP DATABASE IF EXISTS CAVE_TEST; 2 | CREATE DATABASE CAVE_TEST; 3 | USE CAVE_TEST; 4 | 5 | 6 | CREATE TABLE kingdom ( 7 | id int(11) NOT NULL AUTO_INCREMENT, 8 | name varchar(50) NOT NULL, 9 | PRIMARY KEY (id) 10 | ); 11 | 12 | INSERT INTO kingdom VALUES (1,'plant'),(2,'animal'),(3,'fungi'); 13 | 14 | CREATE TABLE organism ( 15 | id int(11) NOT NULL AUTO_INCREMENT, 16 | name varchar(50) NOT NULL, 17 | kingdom_id int(11) DEFAULT NULL, 18 | PRIMARY KEY (id), 19 | KEY kingdom_id (kingdom_id), 20 | CONSTRAINT organism_ibfk_1 FOREIGN KEY (kingdom_id) REFERENCES kingdom (id) ON DELETE CASCADE ON UPDATE CASCADE 21 | ); 22 | 23 | 24 | INSERT INTO organism VALUES (1,'dog',2),(2,'mushroom',3); 25 | 26 | CREATE TABLE individual ( 27 | id int(11) NOT NULL AUTO_INCREMENT, 28 | name varchar(50) NOT NULL, 29 | organism_id int(11) NOT NULL, 30 | PRIMARY KEY (id), 31 | KEY organism_id (organism_id), 32 | CONSTRAINT individual_ibfk_1 FOREIGN KEY (organism_id) REFERENCES organism (id) 33 | ON DELETE CASCADE 34 | ON UPDATE CASCADE 35 | ); 36 | 37 | INSERT INTO individual VALUES (3,'Fido',1),(4,'Freddy',2); 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | select * from individual i join organism o on o.id=i.organism_id join kingdom k on k.id=o.kingdom_id LIMIT 0, 1000 46 | -------------------------------------------------------------------------------- /059_Online_Shop.sql: -------------------------------------------------------------------------------- 1 | DROP DATABASE IF EXISTS CAVE_ONLINE_SHOP; 2 | CREATE DATABASE CAVE_ONLINE_SHOP; 3 | USE CAVE_ONLINE_SHOP; 4 | 5 | create table categories (id int primary key auto_increment, name varchar(50) not null); 6 | insert into categories (name) values ('Books'), ('Films'), ('Music'); 7 | 8 | create table products (id int primary key auto_increment, 9 | name varchar(100) not null, price decimal(7, 2) not null, category_id int not null, 10 | quantity_available int default 0, 11 | foreign key (category_id) references categories(id)); 12 | 13 | insert into products (name, price, category_id, quantity_available) values 14 | ('The 39 Steps', 2.99, 1, 200), 15 | ('The Exorcist', 6.99, 1, 100), 16 | ('The Man Who Mistook His Wife for a Hat', 7.99, 1, 200), 17 | ('Withnail and I', 8.99, 2, 400), 18 | ('Before Sunrise', 8.99, 2, 300), 19 | ('Groundhog Day', 7.99, 2, 200), 20 | ('Easy Rider', 6.99, 2, 300), 21 | ('David Bowie Greatest Hits', 9.99, 3, 200), 22 | ('Depeche Mode Greatest Hits', 9.99, 3, 200); 23 | 24 | create table customers (id int primary key auto_increment, name varchar(100) not null, 25 | email varchar(80) not null); 26 | 27 | insert into customers (name, email) values 28 | ('Chris Walken', 'chris@caveofprogramming.com'), 29 | ('Mike Mikkelson', 'mike@quantumlifetime.com'), 30 | ('Rog Blake', 'blake@fascinatingexperiments.com'); 31 | 32 | create table sales (id int primary key auto_increment, 33 | customer_id int not null, 34 | product_id int not null, 35 | sold_at datetime, 36 | transaction_value decimal(7, 2) default 0, 37 | foreign key (customer_id) references customers(id), 38 | foreign key (product_id) references products(id) 39 | ); 40 | 41 | insert into sales (customer_id, product_id, sold_at, transaction_value) 42 | values 43 | (1, 4, '2015-03-13 12:24:43', 8.99), 44 | (2, 2, '2015-03-12 11:04:12', 6.99), 45 | (1, 7, '2015-03-12 11:14:12', 6.99), 46 | (3, 2, '2015-03-11 11:05:12', 6.99), 47 | (3, 8, '2015-03-12 11:07:12', 9.99), 48 | (1, 2, '2015-03-11 11:14:12', 6.99), 49 | (2, 4, '2015-03-12 11:04:12', 8.99), 50 | (1, 1, '2015-03-14 11:34:12', 2.99); 51 | 52 | select * from customers c join sales s on s.customer_id=c.id join products p on p.id=s.product_id 53 | join categories cat on cat.id=p.category_id 54 | -------------------------------------------------------------------------------- /063_Adding_Columns.sql: -------------------------------------------------------------------------------- 1 | DROP DATABASE IF EXISTS CAVE_TEST; 2 | CREATE DATABASE CAVE_TEST; 3 | USE CAVE_TEST; 4 | 5 | create table person (id int primary key auto_increment); 6 | alter table person add column name varchar(50) not null after id; 7 | alter table person drop column name; 8 | -------------------------------------------------------------------------------- /064_Adding_Foreign_keys.sql: -------------------------------------------------------------------------------- 1 | DROP DATABASE IF EXISTS CAVE_TEST; 2 | CREATE DATABASE CAVE_TEST; 3 | USE CAVE_TEST; 4 | 5 | 6 | create table book (id int primary key auto_increment, name varchar(50), library int); 7 | create table library(id int auto_increment primary key, name varchar(50)); 8 | insert into library (id, name) values (10, 'Cardiff Church Road'), (11, 'Nottingham Orchard Way'); 9 | 10 | insert into book (name, library) values ('The 39 Steps', 10); 11 | 12 | alter table book add constraint fk_book_library foreign key (library) references library(id); 13 | 14 | alter table book drop foreign key fk_book_library; 15 | -------------------------------------------------------------------------------- /065_Adding_Indexes.sql: -------------------------------------------------------------------------------- 1 | DROP DATABASE IF EXISTS CAVE_TEST; 2 | CREATE DATABASE CAVE_TEST; 3 | USE CAVE_TEST; 4 | 5 | CREATE TABLE `music` ( 6 | `id` int(11) NOT NULL AUTO_INCREMENT, 7 | `band` varchar(50) NOT NULL, 8 | `song` varchar(50) NOT NULL, 9 | PRIMARY KEY (`id`) 10 | ); 11 | 12 | alter table music add index idx_band(band); 13 | alter table music drop index idx_band; 14 | -------------------------------------------------------------------------------- /066_Indexing_Multiple_Columns.sql: -------------------------------------------------------------------------------- 1 | USE CAVE_TEST; 2 | 3 | alter table music add index idx_band(band,song); 4 | -------------------------------------------------------------------------------- /069_Views.sql: -------------------------------------------------------------------------------- 1 | DROP DATABASE IF EXISTS CAVE_TEST; 2 | CREATE DATABASE CAVE_TEST; 3 | USE CAVE_TEST; 4 | 5 | create table book(id int primary key auto_increment, name varchar(50) not null, notes varchar(100)); 6 | 7 | create view bookview as select id, name from book; 8 | show full tables; 9 | 10 | select * from bookview LIMIT 0, 1000; 11 | insert into bookview (id, name) values (2, "War and Peace"); 12 | drop view bookview; 13 | -------------------------------------------------------------------------------- /070_View_Algorithms.sql: -------------------------------------------------------------------------------- 1 | USE CAVE_ONLINE_SHOP; 2 | 3 | create algorithm=merge view customer_sales1 as select c.id as customer_id, sold_at from sales s join customers c on c.id=s.customer_id; 4 | 5 | create algorithm=temptable view customer_sales2 as select c.id as customer_id, sold_at from sales s join customers c on c.id=s.customer_id; 6 | 7 | create algorithm=undefined view customer_sales3 as select c.id as customer_id, sold_at from sales s join customers c on c.id=s.customer_id; 8 | 9 | 10 | -------------------------------------------------------------------------------- /071_With_Check_Option.sql: -------------------------------------------------------------------------------- 1 | DROP DATABASE IF EXISTS CAVE_TEST; 2 | CREATE DATABASE CAVE_TEST; 3 | USE CAVE_TEST; 4 | 5 | create table book (id int primary key auto_increment, name varchar(50) not null); 6 | 7 | insert into book (id, name) values (1, "The Thirty-Nine Steps"); 8 | 9 | insert into book (id, name) values (20, "War and Peace"); 10 | 11 | create view bookview as select id, name from book where id < 20 with check option; 12 | 13 | drop view bookview; 14 | -------------------------------------------------------------------------------- /074_Using_Variables.sql: -------------------------------------------------------------------------------- 1 | USE CAVE_ONLINE_SHOP; 2 | 3 | set @user = "John"; 4 | select @user; 5 | 6 | set @some_value = 99; 7 | select @some_value; 8 | 9 | set @min_value = 8.99; 10 | select * from sales where transaction_value > @min_value; 11 | -------------------------------------------------------------------------------- /075_Setting_Variables_With_Selects.sql: -------------------------------------------------------------------------------- 1 | USE CAVE_ONLINE_SHOP; 2 | 3 | select @total := sum(transaction_value), @min_value := min(transaction_value) from sales; 4 | 5 | select @total; 6 | select @min_value; 7 | -------------------------------------------------------------------------------- /076_Select_Update_Example.sql: -------------------------------------------------------------------------------- 1 | USE CAVE_ONLINE_SHOP; 2 | 3 | CREATE TABLE `sales_history` ( 4 | `recorded` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 5 | `total` decimal(10,2) DEFAULT NULL 6 | ); 7 | 8 | 9 | select @total := sum(transaction_value) from sales; 10 | insert into sales_history (recorded, total) values (now(), @total); 11 | 12 | 13 | 14 | 15 | select * from sales_history; 16 | 17 | explain insert into sales_history (recorded, total) values (now(), (select sum(transaction_value) from sales)); 18 | -------------------------------------------------------------------------------- /077_Fixing_Select_Update_With_Table_Locks.sql: -------------------------------------------------------------------------------- 1 | USE CAVE_ONLINE_SHOP; 2 | 3 | 4 | lock tables sales read, sales_history write; 5 | select @total := sum(transaction_value) from sales; 6 | insert into sales_history (recorded, total) values (now(), @total); 7 | unlock tables; 8 | 9 | 10 | insert into sales (customer_id, product_id, sold_at, transaction_value) 11 | values 12 | (1, 1, now(), 88.77); 13 | 14 | select * from sales_history; 15 | -------------------------------------------------------------------------------- /079_A_Simple_Transaction.sql: -------------------------------------------------------------------------------- 1 | DROP DATABASE IF EXISTS CAVE_TEST; 2 | CREATE DATABASE CAVE_TEST; 3 | USE CAVE_TEST; 4 | 5 | create table books(id int primary key auto_increment, name varchar(50)); 6 | 7 | set autocommit=0; 8 | 9 | insert into books (name) values ('The Universe'); 10 | 11 | delete from books where id=3; 12 | 13 | update books set name = "The Mountain Version 2" where id=4; 14 | 15 | 16 | select * from books; 17 | 18 | commit; 19 | -- or -- 20 | rollback; 21 | -------------------------------------------------------------------------------- /082_Demonstrating_Isolation_Levels_and_Row_Locking.sql: -------------------------------------------------------------------------------- 1 | -- Database isolation levels 2 | 3 | -- Serializable 4 | -- Repeatable read 5 | -- Read committed 6 | -- Read uncommitted 7 | 8 | USE CAVE_TEST; 9 | 10 | -- Connection 1 11 | set transaction isolation level serializable; 12 | 13 | start transaction; 14 | 15 | select * from books; 16 | 17 | commit; 18 | 19 | 20 | -- Connection 2 21 | 22 | select @@session.tx_isolation; 23 | 24 | start transaction; 25 | 26 | select * from books; 27 | 28 | update books set name = "The Mountain" where id=4; 29 | 30 | commit; 31 | -------------------------------------------------------------------------------- /087_Select_for_Update.sql: -------------------------------------------------------------------------------- 1 | DROP DATABASE IF EXISTS CAVE_TEST; 2 | CREATE DATABASE CAVE_TEST; 3 | USE CAVE_TEST; 4 | 5 | create table accounts(id int primary key auto_increment, balance numeric(10,2) default 0); 6 | 7 | select * from accounts; 8 | 9 | 10 | start transaction; 11 | 12 | set @withdraw = 500; 13 | set @account = 1; 14 | 15 | select balance from accounts where id=@account for update; 16 | 17 | -- Check that the balance is bigger than the withdrawal amount 18 | 19 | update accounts set balance = balance - @withdraw where id=@account; 20 | 21 | commit; 22 | -------------------------------------------------------------------------------- /088_Lock_in_Share_Mode.sql: -------------------------------------------------------------------------------- 1 | DROP DATABASE IF EXISTS CAVE_TEST; 2 | CREATE DATABASE CAVE_TEST; 3 | USE CAVE_TEST; 4 | 5 | create table libraries (id int primary key auto_increment, name varchar(50) not null); 6 | create table books (id int primary key auto_increment, title varchar(50) not null, library_id int not null, foreign key (library_id) references libraries(id)); 7 | 8 | insert into libraries (name) values ('York'); 9 | insert into libraries (name) values ('Nottingham'); 10 | insert into libraries (name) values ('Manchester'); 11 | 12 | start transaction; 13 | 14 | select id from libraries where name="Nottingham" lock in share mode; 15 | 16 | insert into books (title, library_id) values ("Painting for Beginners", 2); 17 | 18 | commit; 19 | -------------------------------------------------------------------------------- /089_String_functions.sql: -------------------------------------------------------------------------------- 1 | USE CAVE_TEST; 2 | 3 | show tables; 4 | 5 | select * from books; 6 | 7 | select concat("Title: ", title) from books; 8 | 9 | select concat('My', ' ', 'name is', ' ', 'John'); 10 | 11 | select lcase('Fred'); 12 | 13 | select ucase(left('England', 2)); 14 | 15 | select trim(' fox '); 16 | 17 | set @greeting = 'Hello Bob. How are you?'; 18 | 19 | select substr(@greeting, 7, 3); 20 | -------------------------------------------------------------------------------- /090_Date_Functions.sql: -------------------------------------------------------------------------------- 1 | DROP DATABASE IF EXISTS CAVE_TEST; 2 | CREATE DATABASE CAVE_TEST; 3 | USE CAVE_TEST; 4 | 5 | create table dates(id int primary key auto_increment, applied date not null); 6 | 7 | select curdate(); 8 | 9 | insert into dates (applied) values (curdate() - interval 10 year); 10 | 11 | select * from dates; 12 | 13 | select curdate() + interval 36 day; 14 | 15 | select date_sub('2010-06-16', interval 5 month); 16 | 17 | select id, year(applied) from dates where applied = '2011-02-08'; 18 | 19 | set @born = '1974-05-15'; 20 | 21 | select dayname(@born); 22 | 23 | select from_days(datediff(curdate(), @born)); 24 | -------------------------------------------------------------------------------- /091_Control_Flow_Functions.sql: -------------------------------------------------------------------------------- 1 | DROP DATABASE IF EXISTS CAVE_TEST; 2 | CREATE DATABASE CAVE_TEST; 3 | USE CAVE_TEST; 4 | 5 | create table parts(id int primary key auto_increment, part_id varchar(20) default null, catalog_id varchar(20) not null); 6 | 7 | insert into parts(part_id, catalog_id) values (null, 'AB126'); 8 | 9 | select if(part_id is not null, part_id, catalog_id) as identifier from parts; 10 | 11 | select if(part_id is not null, part_id, catalog_id) as identifier from parts 12 | where if(part_id is not null, part_id, catalog_id) = 'XYZ35'; 13 | 14 | select * from parts; 15 | 16 | select ifnull(part_id, catalog_id) as identifier from parts; 17 | -------------------------------------------------------------------------------- /092_Casting.sql: -------------------------------------------------------------------------------- 1 | USE CAVE_TEST; 2 | 3 | select cast('1974-05-15' as char); 4 | 5 | show tables; 6 | 7 | select concat("Number of books: ", cast(count(*) as char)) from books; 8 | -------------------------------------------------------------------------------- /099_Hello_World.sql: -------------------------------------------------------------------------------- 1 | DROP DATABASE IF EXISTS CAVE_TEST; 2 | CREATE DATABASE CAVE_TEST; 3 | USE CAVE_TEST; 4 | 5 | delimiter ;; 6 | 7 | use CAVE_TEST;; 8 | 9 | 10 | create procedure HelloWorld() 11 | begin 12 | select "Hello World!!!"; 13 | end;; 14 | 15 | call HelloWorld();; 16 | 17 | drop procedure HelloWorld; 18 | -------------------------------------------------------------------------------- /100_Setting_the_Definer.sql: -------------------------------------------------------------------------------- 1 | USE CAVE_ONLINE_SHOP; 2 | 3 | show tables; 4 | 5 | select * from products; 6 | 7 | create user shopuser@localhost identified by 'hello'; 8 | 9 | DELIMITER $$ 10 | 11 | -- or: sql security invoker 12 | 13 | CREATE definer=shopuser@localhost PROCEDURE `ShowCustomers`() 14 | sql security invoker 15 | begin 16 | select * from customers; 17 | end$$ 18 | 19 | DELIMITER ; 20 | 21 | call ShowCustomers(); 22 | 23 | drop procedure ShowCustomers; 24 | DROP USER shopuser@localhost; 25 | -------------------------------------------------------------------------------- /101_Procedure_Permission_Example.sql: -------------------------------------------------------------------------------- 1 | 2 | 3 | USE CAVE_ONLINE_SHOP; 4 | 5 | select * from customers; 6 | create user runhelloworld@localhost identified by 'hello'; 7 | 8 | DELIMITER $$ 9 | 10 | 11 | 12 | CREATE definer=runhelloworld@localhost PROCEDURE `HelloWorld`() 13 | sql security definer 14 | begin 15 | select * from customers; 16 | end$$ 17 | 18 | DELIMITER ; 19 | 20 | grant execute on procedure CAVE_ONLINE_SHOP.HelloWorld to runhelloworld@localhost; 21 | 22 | grant select on CAVE_ONLINE_SHOP.customers to runhelloworld@localhost; 23 | 24 | call HelloWorld(); 25 | 26 | drop procedure HelloWorld; 27 | 28 | drop user runhelloworld@localhost; 29 | -------------------------------------------------------------------------------- /102_Procedure_Permissions.sql: -------------------------------------------------------------------------------- 1 | 2 | USE CAVE_ONLINE_SHOP; 3 | 4 | show tables; 5 | 6 | select * from products; 7 | 8 | create user shopuser@localhost identified by 'hello'; 9 | create user procuser@localhost identified by 'hello'; 10 | 11 | 12 | 13 | DELIMITER $$ 14 | 15 | CREATE definer=shopuser@localhost PROCEDURE `ShowCustomers`() 16 | sql security definer 17 | begin 18 | select * from customers; 19 | end$$ 20 | 21 | DELIMITER ; 22 | 23 | grant execute on procedure CAVE_ONLINE_SHOP.ShowCustomers to shopuser@localhost; 24 | grant select on CAVE_ONLINE_SHOP.customers to shopuser@localhost; 25 | 26 | grant select on CAVE_ONLINE_SHOP.products to procuser@localhost ; 27 | grant execute on procedure CAVE_ONLINE_SHOP.ShowCustomers to procuser@localhost ; 28 | 29 | 30 | call ShowCustomers(); 31 | 32 | drop user shopuser@localhost; 33 | drop user procuser@localhost; 34 | drop procedure ShowCustomers; 35 | -------------------------------------------------------------------------------- /103_Passing_Parameters.sql: -------------------------------------------------------------------------------- 1 | USE CAVE_TEST; 2 | 3 | show tables; 4 | 5 | select * from books; 6 | 7 | DELIMITER $$ 8 | 9 | CREATE PROCEDURE `ShowBooks`(in maxId int) 10 | begin 11 | select * from books where id < maxId; 12 | end$$ 13 | 14 | DELIMITER ; 15 | 16 | call ShowBooks(4); 17 | 18 | drop procedure ShowBooks; 19 | -------------------------------------------------------------------------------- /106_Out_Parameters.sql: -------------------------------------------------------------------------------- 1 | USE CAVE_TEST; 2 | 3 | select * from books; 4 | select id, title into @theId, @theTitle from books where id=1; 5 | 6 | 7 | select @theId, @theTitle; 8 | 9 | DELIMITER $$ 10 | 11 | CREATE PROCEDURE `ShowBooks`(in theId int, out outId int, out outTitle varchar(50)) 12 | begin 13 | select id, title into outId, outTitle from books where id = theId; 14 | end$$ 15 | 16 | DELIMITER ; 17 | 18 | call ShowBooks(4, @id, @title); 19 | 20 | select @id, @title; 21 | 22 | drop procedure ShowBooks; 23 | -------------------------------------------------------------------------------- /108_If.sql: -------------------------------------------------------------------------------- 1 | USE CAVE_TEST; 2 | 3 | show tables; 4 | 5 | select * from accounts; 6 | 7 | delimiter // 8 | 9 | create procedure withdraw(in flag bool) 10 | begin 11 | 12 | if flag=true then 13 | select "Hello"; 14 | else 15 | select "Goodbye"; 16 | end if; 17 | 18 | end// 19 | 20 | delimiter ; 21 | 22 | call withdraw(true); 23 | 24 | drop procedure withdraw; 25 | -------------------------------------------------------------------------------- /109_Local_Variables.sql: -------------------------------------------------------------------------------- 1 | USE CAVE_TEST; 2 | 3 | delimiter // 4 | 5 | create procedure withdraw(in flag bool) 6 | begin 7 | 8 | declare current_balance numeric(7, 2) default 0.0; 9 | 10 | select current_balance; 11 | 12 | -- Check the current balance of the account 13 | -- If balance big enough, do withdrawal 14 | 15 | end// 16 | 17 | delimiter ; 18 | 19 | drop procedure withdraw; 20 | -------------------------------------------------------------------------------- /110_Account_Withdrawal.sql: -------------------------------------------------------------------------------- 1 | USE CAVE_TEST; 2 | 3 | delimiter // 4 | 5 | create procedure withdraw(in account_id int, in amount numeric(7, 2), out success bool) 6 | begin 7 | 8 | declare current_balance numeric(7, 2) default 0.0; 9 | 10 | select balance into current_balance from accounts where id=account_id; 11 | 12 | if current_balance >= amount then 13 | update accounts set balance = balance - amount where id=account_id; 14 | set success=true; 15 | else 16 | set success=false; 17 | end if; 18 | 19 | -- Check the current balance of the account 20 | -- If balance big enough, do withdrawal 21 | 22 | end// 23 | 24 | delimiter ; 25 | 26 | call withdraw(1, 251, @success); 27 | 28 | select @success; 29 | 30 | drop procedure withdraw; 31 | -------------------------------------------------------------------------------- /111_Transactional_Withdrawal.sql: -------------------------------------------------------------------------------- 1 | USE CAVE_TEST; 2 | 3 | delimiter // 4 | 5 | create procedure withdraw(in account_id int, in amount numeric(7, 2), out success bool) 6 | begin 7 | 8 | declare current_balance numeric(7, 2) default 0.0; 9 | 10 | start transaction; 11 | 12 | select balance into current_balance from accounts where id=account_id for update; 13 | 14 | if current_balance >= amount then 15 | update accounts set balance = balance - amount where id=account_id; 16 | set success=true; 17 | else 18 | set success=false; 19 | end if; 20 | 21 | commit; 22 | 23 | end// 24 | 25 | delimiter ; 26 | 27 | drop procedure withdraw; 28 | -------------------------------------------------------------------------------- /113_Error_Handlers.sql: -------------------------------------------------------------------------------- 1 | USE CAVE_TEST; 2 | 3 | delimiter // 4 | 5 | create procedure withdraw(in account_id int, in amount numeric(7, 2), out success bool) 6 | begin 7 | 8 | declare current_balance numeric(7, 2) default 0.0; 9 | 10 | declare exit handler for sqlexception 11 | begin 12 | show errors; 13 | end; 14 | 15 | declare exit handler for sqlwarning 16 | begin 17 | show warnings; 18 | end; 19 | 20 | start transaction; 21 | 22 | select balance into current_balance from accounts where id=account_id for update; 23 | 24 | if current_balance >= amount then 25 | update accounts set balance = balance - amount where id=account_id; 26 | set success=true; 27 | else 28 | set success=false; 29 | end if; 30 | 31 | commit; 32 | 33 | end// 34 | 35 | delimiter ; 36 | 37 | drop procedure withdraw; 38 | -------------------------------------------------------------------------------- /114_While_Loops.sql: -------------------------------------------------------------------------------- 1 | USE CAVE_TEST; 2 | 3 | delimiter $$ 4 | 5 | create procedure whiledemo() 6 | begin 7 | 8 | declare count int default 0; 9 | declare numbers varchar(30) default ""; 10 | 11 | 12 | while count < 10 do 13 | 14 | set numbers := concat(numbers, count); 15 | 16 | set count := count + 1; 17 | 18 | end while; 19 | 20 | select numbers; 21 | 22 | end$$ 23 | 24 | delimiter ; 25 | 26 | 27 | call whiledemo(); 28 | 29 | drop procedure whiledemo; 30 | -------------------------------------------------------------------------------- /115_Labelled_Loops.sql: -------------------------------------------------------------------------------- 1 | USE CAVE_TEST; 2 | 3 | delimiter $$ 4 | 5 | create procedure loopdemo() 6 | begin 7 | 8 | declare count int default 0; 9 | declare numberlist varchar(30) default ""; 10 | 11 | the_loop: loop 12 | 13 | if count = 10 then 14 | leave the_loop; 15 | end if; 16 | 17 | set numberlist := concat(numberlist, count); 18 | 19 | if count != 9 then 20 | set numberlist := concat(numberlist, ", "); 21 | end if; 22 | 23 | set count := count + 1; 24 | 25 | end loop; 26 | 27 | select numberlist; 28 | 29 | end$$ 30 | 31 | 32 | delimiter ; 33 | 34 | call loopdemo(); 35 | 36 | 37 | drop procedure loopdemo; 38 | -------------------------------------------------------------------------------- /116_Generating_Random_Data.sql: -------------------------------------------------------------------------------- 1 | -- id 2 | -- email: user1@caveofprogramming.com, user2@caveofprogramming.com, ... 3 | -- random date 4 | -- enabled (random boolean) 5 | 6 | DROP DATABASE IF EXISTS CAVE_TEST; 7 | CREATE DATABASE CAVE_TEST; 8 | USE CAVE_TEST; 9 | 10 | create table users (id int auto_increment primary key, email varchar(40) not null, registered date not null, 11 | active boolean default false); 12 | 13 | use test; 14 | 15 | select round(rand()); 16 | 17 | select date(now()) - interval floor(10000*rand()) day; 18 | 19 | 20 | drop table if exists users; 21 | 22 | show tables; 23 | -------------------------------------------------------------------------------- /117_A_Data_Generating_Procedure.sql: -------------------------------------------------------------------------------- 1 | -- id 2 | -- email: user1@caveofprogramming.com, user2@caveofprogramming.com, ... 3 | -- random date 4 | -- enabled (random boolean) 5 | 6 | DROP DATABASE IF EXISTS CAVE_TEST; 7 | CREATE DATABASE CAVE_TEST; 8 | USE CAVE_TEST; 9 | 10 | create table users (id int auto_increment primary key, email varchar(40) not null, registered date not null, 11 | active boolean default false); 12 | 13 | use test; 14 | 15 | select round(rand()); 16 | 17 | select date(now()) - interval floor(10000*rand()) day; 18 | 19 | drop table if exists users; 20 | 21 | show tables; 22 | 23 | delimiter $$ 24 | 25 | create procedure CAVE_TEST.testdata() 26 | begin 27 | 28 | declare NUMROWS int default 10000; 29 | declare count int default 0; 30 | 31 | declare registered_value date default null; 32 | declare email_value varchar(40) default null; 33 | declare active_value boolean default false; 34 | 35 | drop table if exists users; 36 | 37 | create table users (id int auto_increment primary key, email varchar(40) not null, registered date not null, 38 | active boolean default false); 39 | 40 | while count < NUMROWS do 41 | 42 | set registered_value := date(now()) - interval floor(10000*rand()) day; 43 | set active_value := round(rand()); 44 | set email_value := concat("user", count, "@caveofprogramming.com"); 45 | 46 | insert into CAVE_TEST.users (email, registered, active) values (email_value, registered_value, active_value); 47 | 48 | set count := count + 1; 49 | end while; 50 | 51 | 52 | end$$ 53 | 54 | 55 | delimiter ; 56 | 57 | 58 | 59 | call CAVE_TEST.testdata(); 60 | drop procedure CAVE_TEST.testdata; 61 | 62 | show tables; 63 | 64 | select count(*) from CAVE_TEST.users; 65 | select * from CAVE_TEST.users; 66 | -------------------------------------------------------------------------------- /118_Cursors.sql: -------------------------------------------------------------------------------- 1 | USE CAVE_TEST; 2 | 3 | desc users; 4 | 5 | delimiter $$ 6 | 7 | create procedure cursortest() 8 | begin 9 | 10 | declare the_email varchar(40); 11 | 12 | declare cur1 cursor for select email from users order by id; 13 | 14 | open cur1; 15 | 16 | fetch cur1 into the_email; 17 | 18 | close cur1; 19 | 20 | select the_email; 21 | 22 | end$$ 23 | 24 | delimiter ; 25 | 26 | call cursortest(); 27 | 28 | drop procedure cursortest; 29 | 30 | select * from users; 31 | -------------------------------------------------------------------------------- /119_Fetching_Cursor_Data_With_Loops.sql: -------------------------------------------------------------------------------- 1 | USE CAVE_TEST; 2 | 3 | desc users; 4 | 5 | 6 | set sql_safe_updates=0; 7 | 8 | drop table if exists leads; 9 | 10 | create table leads(id int auto_increment primary key, email varchar(40) not null); 11 | 12 | delimiter $$ 13 | 14 | create procedure CAVE_TEST.cursortest() 15 | begin 16 | 17 | declare the_email varchar(40); 18 | declare finished boolean default false; 19 | 20 | declare cur1 cursor for select email from users where active = true and registered > date(now()) - interval 1 year; 21 | 22 | declare continue handler for not found set finished := true; 23 | 24 | delete from leads; 25 | 26 | open cur1; 27 | 28 | the_loop: loop 29 | 30 | fetch cur1 into the_email; 31 | 32 | if finished then 33 | leave the_loop; 34 | end if; 35 | 36 | insert into CAVE_TEST.leads (email) values (the_email); 37 | 38 | end loop the_loop; 39 | 40 | close cur1; 41 | 42 | end$$ 43 | 44 | delimiter ; 45 | 46 | 47 | 48 | call cursortest(); 49 | 50 | drop procedure cursortest; 51 | 52 | select * from users; 53 | 54 | 55 | select count(*) from leads; 56 | -------------------------------------------------------------------------------- /120_Case_Expression.sql: -------------------------------------------------------------------------------- 1 | 2 | DROP DATABASE IF EXISTS CAVE_TEST; 3 | CREATE DATABASE CAVE_TEST; 4 | USE CAVE_TEST; 5 | 6 | create table products(id int primary key auto_increment, product varchar(40) not null, category enum('bakery', 'fruit', 'vegetable')); 7 | 8 | insert into products (product, category) values ('cat treats', null); 9 | 10 | create table fruits(id int primary key, product varchar(40) not null); 11 | create table vegetables(id int primary key, product varchar(40) not null); 12 | create table bakery(id int primary key, product varchar(40) not null); 13 | 14 | select id, product, category from products order by id; 15 | 16 | show tables; 17 | 18 | delimiter $$ 19 | 20 | create procedure filltables(out unassigned longtext) 21 | begin 22 | 23 | declare the_id int; 24 | declare the_product varchar(40); 25 | declare the_category enum('bakery', 'fruit', 'vegetable'); 26 | declare finished boolean default false; 27 | 28 | declare cur cursor for select id, product, category from products order by id; 29 | 30 | declare continue handler for not found set finished := true; 31 | 32 | open cur; 33 | 34 | set unassigned := ""; 35 | 36 | the_loop: loop 37 | 38 | fetch cur into the_id, the_product, the_category; 39 | 40 | if finished = true then 41 | leave the_loop; 42 | end if; 43 | 44 | case the_category 45 | when 'fruit' then 46 | insert into fruits (id, product) values (the_id, the_product); 47 | when 'vegetable' then 48 | insert into vegetables (id, product) values (the_id, the_product); 49 | when 'bakery' then 50 | insert into bakery (id, product) values (the_id, the_product); 51 | else 52 | set unassigned := concat(unassigned, the_product, ", "); 53 | end case; 54 | 55 | end loop; 56 | 57 | 58 | close cur; 59 | 60 | 61 | end$$ 62 | 63 | delimiter ; 64 | 65 | select * from products; 66 | 67 | 68 | call filltables(@unassigned); 69 | 70 | select * from fruits; 71 | select * from vegetables; 72 | select * from bakery; 73 | 74 | select @unassigned; 75 | 76 | drop procedure filltables; 77 | -------------------------------------------------------------------------------- /123_Solutions4.sql: -------------------------------------------------------------------------------- 1 | DROP DATABASE IF EXISTS CAVE_TEST; 2 | CREATE DATABASE CAVE_TEST; 3 | USE CAVE_TEST; 4 | -- 5 | -- 1. Create table of words and adjectives and populate it. 6 | -- 7 | 8 | 9 | create table words(id int primary key auto_increment, noun varchar(20) not null, adjective varchar(20) not null); 10 | 11 | 12 | insert into words (noun, adjective) values ("sun", "fast"); 13 | insert into words (noun, adjective) values ("chair", "slow"); 14 | insert into words (noun, adjective) values ("stone", "new"); 15 | insert into words (noun, adjective) values ("dog", "greasy"); 16 | insert into words (noun, adjective) values ("cat", "blue"); 17 | insert into words (noun, adjective) values ("book", "high"); 18 | insert into words (noun, adjective) values ("sky", "evil"); 19 | insert into words (noun, adjective) values ("tree", "beautiful"); 20 | insert into words (noun, adjective) values ("apple", "sly"); 21 | insert into words (noun, adjective) values ("head", "ordinary"); 22 | 23 | 24 | select * from words; 25 | 26 | -- 27 | -- Create procedure that produces lists of nouns and adjectives separately 28 | -- 29 | 30 | delimiter $$ 31 | 32 | create procedure create_lists(out nouns text, out adjectives text) 33 | begin 34 | 35 | declare finished bool default false; 36 | declare the_noun varchar(20); 37 | declare the_adjective varchar(20); 38 | declare first boolean default true; 39 | declare cur cursor for select noun, adjective from words order by id; 40 | 41 | declare continue handler for not found set finished := true; 42 | 43 | set nouns := ""; 44 | set adjectives := ""; 45 | 46 | open cur; 47 | 48 | the_loop: loop 49 | 50 | fetch cur into the_noun, the_adjective; 51 | 52 | if finished then 53 | leave the_loop; 54 | end if; 55 | 56 | -- Deal with the comma. Only add it if 57 | -- this isn't the first record. 58 | if first then 59 | set first := false; 60 | else 61 | set nouns := concat(nouns, ","); 62 | set adjectives := concat(adjectives, ","); 63 | end if; 64 | 65 | -- Now concat the results from the table. 66 | set nouns := concat(nouns, the_noun); 67 | set adjectives := concat(adjectives, the_adjective); 68 | 69 | end loop; 70 | 71 | close cur; 72 | 73 | end$$ 74 | 75 | 76 | delimiter ; 77 | 78 | 79 | call create_lists(@nouns, @adjectives); 80 | 81 | select @nouns, @adjectives; 82 | 83 | drop procedure create_lists; 84 | 85 | -- 86 | -- 2. Generate table of "star" names.alter 87 | -- 88 | 89 | create table stars(id int primary key auto_increment, name varchar(40) not null); 90 | 91 | delimiter $$ 92 | 93 | create procedure create_stars() 94 | begin 95 | 96 | declare the_noun varchar(20); 97 | declare the_adjective varchar(20); 98 | 99 | 100 | declare finished boolean default false; 101 | 102 | declare nouns_cursor cursor for select noun from words order by rand(); 103 | declare adjectives_cursor cursor for select adjective from words order by rand(); 104 | 105 | declare continue handler for not found set finished := true; 106 | 107 | open nouns_cursor; 108 | open adjectives_cursor; 109 | 110 | the_loop: loop 111 | 112 | fetch nouns_cursor into the_noun; 113 | fetch adjectives_cursor into the_adjective; 114 | 115 | if finished then 116 | leave the_loop; 117 | end if; 118 | 119 | -- Uppercase first letters 120 | set the_adjective = concat(ucase(left(the_adjective, 1)), substring(the_adjective, 2)); 121 | set the_noun = concat(ucase(left(the_noun, 1)), substring(the_noun, 2)); 122 | 123 | insert into stars (name) values (concat(the_adjective, " ", the_noun)); 124 | 125 | end loop; 126 | 127 | close nouns_cursor; 128 | close adjectives_cursor; 129 | 130 | end$$ 131 | 132 | delimiter ; 133 | 134 | call create_stars(); 135 | 136 | drop procedure create_stars; 137 | 138 | select * from stars; 139 | 140 | set sql_safe_updates=0; 141 | delete from stars; 142 | 143 | -- 144 | -- 3 and 4 145 | -- 146 | 147 | alter table stars add column born date; 148 | alter table stars add column died date; 149 | 150 | delimiter $$ 151 | 152 | create procedure create_stars_with_dates() 153 | not deterministic 154 | begin 155 | 156 | declare the_noun varchar(20); 157 | declare the_adjective varchar(20); 158 | declare born_date date; 159 | declare died_date date; 160 | declare min_died date; 161 | declare max_died date; 162 | declare days_lifespan int; 163 | 164 | declare finished boolean default false; 165 | 166 | declare nouns_cursor cursor for select noun from words order by rand(); 167 | declare adjectives_cursor cursor for select adjective from words order by rand(); 168 | 169 | declare continue handler for not found set finished := true; 170 | 171 | open nouns_cursor; 172 | open adjectives_cursor; 173 | 174 | the_loop: loop 175 | 176 | fetch nouns_cursor into the_noun; 177 | fetch adjectives_cursor into the_adjective; 178 | 179 | if finished then 180 | leave the_loop; 181 | end if; 182 | 183 | -- Uppercase first letters 184 | set the_adjective = concat(ucase(left(the_adjective, 1)), substring(the_adjective, 2)); 185 | set the_noun = concat(ucase(left(the_noun, 1)), substring(the_noun, 2)); 186 | 187 | -- Figure out birth date; at least 20 years ago, and not more than 60 years before 188 | -- that (80 years total maximum) 189 | select date(now()) - interval 20 year - interval 365*60*rand() day into born_date; 190 | 191 | -- When was the earliest they could have died? At least 19 years after being born. 192 | select born_date + interval 19 year into min_died; 193 | 194 | set died_date := null; 195 | 196 | if rand() <= 0.4 then 197 | 198 | -- When was the latest they could have died? (Today) 199 | select date(now()) into max_died; 200 | 201 | -- Calculate a random fraction of the interval between the birth date 202 | -- and maximum death date. 203 | select datediff(max_died, min_died)*rand() into days_lifespan; 204 | 205 | -- Add this number of days to when they were born to get the death date. 206 | select born_date + interval 19 year + interval days_lifespan day into died_date; 207 | 208 | end if; 209 | 210 | insert into stars (name, born, died) values (concat(the_adjective, " ", the_noun), born_date, died_date); 211 | 212 | end loop; 213 | 214 | close nouns_cursor; 215 | close adjectives_cursor; 216 | 217 | end$$ 218 | 219 | delimiter ; 220 | 221 | delete from stars; 222 | 223 | call create_stars_with_dates(); 224 | drop procedure create_stars_with_dates; 225 | 226 | select from_days(datediff(died, born)) from stars where died is not null; 227 | 228 | 229 | select * from stars; 230 | -------------------------------------------------------------------------------- /124_Introducing_Triggers.sql: -------------------------------------------------------------------------------- 1 | DROP DATABASE IF EXISTS CAVE_TEST; 2 | CREATE DATABASE CAVE_TEST; 3 | USE CAVE_TEST; 4 | 5 | create table sales(id int primary key, product varchar(30) not null, value numeric(10,2)); 6 | 7 | create table sales_update( 8 | id int primary key auto_increment, 9 | product_id int not null, 10 | changed_at timestamp, 11 | before_value numeric(10,2) not null, 12 | after_value numeric(10,2) not null); 13 | 14 | 15 | insert into sales (id, product, value) values (3, "Cake", 0.80); 16 | 17 | select * from sales; 18 | 19 | update sales set value = 0.60 where id = 3; 20 | 21 | delimiter $$ 22 | 23 | create trigger before_sales_update before update on sales for each row 24 | begin 25 | 26 | insert into sales_update(product_id, changed_at, before_value, after_value) 27 | value (old.id, now(), old.value, new.value); 28 | 29 | end$$ 30 | 31 | 32 | delimiter ; 33 | 34 | select * from sales_update; 35 | 36 | drop table sales_update; 37 | -------------------------------------------------------------------------------- /125_Triggers_and_Validation.sql: -------------------------------------------------------------------------------- 1 | DROP DATABASE IF EXISTS CAVE_TEST; 2 | CREATE DATABASE CAVE_TEST; 3 | USE CAVE_TEST; 4 | 5 | create table products (id int primary key auto_increment, value numeric(10,2) not null); 6 | 7 | delimiter $$ 8 | 9 | create trigger before_products_insert before insert on products for each row 10 | begin 11 | 12 | if new.value > 100.0 then 13 | set new.value := 100.0; 14 | end if; 15 | 16 | end$$ 17 | 18 | create trigger before_products_update before update on products for each row 19 | begin 20 | 21 | if new.value > 100.0 then 22 | set new.value := 100.0; 23 | end if; 24 | 25 | end$$ 26 | 27 | delimiter ; 28 | 29 | 30 | insert into products (value) values (500); 31 | 32 | update products set value = 102 where id=1; 33 | 34 | select * from products; 35 | -------------------------------------------------------------------------------- /126_Triggers_and_Transactions.sql: -------------------------------------------------------------------------------- 1 | DROP DATABASE IF EXISTS CAVE_TEST; 2 | CREATE DATABASE CAVE_TEST; 3 | USE CAVE_TEST; 4 | 5 | show tables; 6 | 7 | create table sales(id int primary key auto_increment, product varchar(45) not null, sold numeric(8,2) not null); 8 | 9 | create table sales_totals(id int primary key auto_increment, total numeric(11,2) not null, day date); 10 | 11 | alter table sales_totals add unique (day); 12 | 13 | show index from sales_totals; 14 | 15 | 16 | delimiter $$ 17 | 18 | create trigger before_sales_insert before insert on sales for each row 19 | begin 20 | 21 | declare today date default date(now()); 22 | declare count int default 0; 23 | 24 | select count(*) from sales_totals where day = today into count for update; 25 | 26 | if count = 0 then 27 | insert into sales_totals (total, day) values (new.sold, today); 28 | else 29 | update sales_totals set total = total + new.sold where day = today; 30 | end if; 31 | 32 | end$$ 33 | 34 | delimiter ; 35 | 36 | drop trigger before_sales_insert; 37 | 38 | select * from sales; 39 | select * from sales_totals; 40 | 41 | 42 | insert into sales (product, sold) values ("Dog Lead Deluxe", 10.00); 43 | 44 | 45 | set sql_safe_updates=0; 46 | delete from sales; 47 | delete from sales_totals; 48 | -------------------------------------------------------------------------------- /127_Triggers_Exercise.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | Create a table of animals that includes a text-type column (e.g. varchar or text) called "animal_name". 4 | 5 | Create a trigger that prevents you from inserting any animal name containing the word "cat". E.g. "Wildcat", "Housecat", etc. 6 | 7 | If someone tries to insert any kind of cat, the trigger should insert "xxx" instead and should log the attempted entry, including the animal name, 8 | in a "violations" table, along with the date and time it occurred. 9 | 10 | Animals 11 | primary key 12 | animal name 13 | (anything else) 14 | 15 | Violations 16 | primary key 17 | animal name 18 | date and time 19 | -------------------------------------------------------------------------------- /128_Solution5.sql: -------------------------------------------------------------------------------- 1 | DROP DATABASE IF EXISTS CAVE_TEST; 2 | CREATE DATABASE CAVE_TEST; 3 | USE CAVE_TEST; 4 | 5 | create table animals (id int primary key auto_increment, animal_name varchar(50) not null); 6 | 7 | create table violations(id int primary key auto_increment, animal_name varchar(50) not null, moment datetime not null); 8 | 9 | 10 | delimiter $$ 11 | 12 | create trigger before_animals_insert before insert on animals for each row 13 | begin 14 | 15 | if new.animal_name like "%cat%" then 16 | 17 | insert into violations (animal_name, moment) values (new.animal_name, now()); 18 | 19 | set new.animal_name = "xxx"; 20 | 21 | end if; 22 | 23 | end$$ 24 | 25 | delimiter ; 26 | 27 | insert into animals (animal_name) values ("Housecat"); 28 | 29 | select * from animals; 30 | select * from violations; 31 | -------------------------------------------------------------------------------- /130_Defining_Functions.sql: -------------------------------------------------------------------------------- 1 | USE CAVE_ONLINE_SHOP; 2 | 3 | show tables; 4 | 5 | select least(6, 4, 9); 6 | 7 | select * from sales; 8 | 9 | select date(sold_at), sum(transaction_value) from sales group by date(sold_at); 10 | 11 | select date('2015-03-11 11:14:12'); 12 | 13 | set @tax = 19; 14 | set @day = '2015-03-11'; 15 | 16 | select sum(transaction_value) * ((100-@tax)/100) from sales where date(sold_at) = @day; 17 | 18 | delimiter $$ 19 | 20 | create function sales_after_tax(tax float, day date) returns numeric(10,2) 21 | begin 22 | 23 | declare result numeric(10,2); 24 | 25 | select sum(transaction_value) * ((100-tax)/100) from sales where date(sold_at) = day into result; 26 | 27 | return result; 28 | 29 | end$$ 30 | 31 | 32 | delimiter ; 33 | 34 | select sales_after_tax(19, '2015-03-11'); 35 | 36 | drop function sales_after_tax; 37 | -------------------------------------------------------------------------------- /135_Art_Shop.sql: -------------------------------------------------------------------------------- 1 | 2 | DROP DATABASE IF EXISTS CAVE_ART_SHOP; 3 | CREATE DATABASE CAVE_ART_SHOP; 4 | USE CAVE_ART_SHOP; 5 | 6 | CREATE TABLE `category` ( 7 | `id` int(11) NOT NULL AUTO_INCREMENT, 8 | `name` varchar(45) NOT NULL, 9 | PRIMARY KEY (`id`) 10 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 11 | 12 | 13 | 14 | CREATE TABLE `customers` ( 15 | `id` int(11) NOT NULL AUTO_INCREMENT, 16 | `name` varchar(45) NOT NULL, 17 | `address_line_1` varchar(45) NOT NULL, 18 | `address_line_2` varchar(45) DEFAULT NULL, 19 | `city` varchar(45) NOT NULL, 20 | `region` varchar(45) DEFAULT NULL, 21 | `country` varchar(45) NOT NULL, 22 | `postcode` varchar(8) NOT NULL, 23 | `registered` datetime NOT NULL, 24 | PRIMARY KEY (`id`) 25 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 26 | 27 | 28 | 29 | CREATE TABLE `artworks` ( 30 | `id` int(11) NOT NULL AUTO_INCREMENT, 31 | `name` varchar(45) NOT NULL, 32 | `description` varchar(250) NOT NULL, 33 | `height` int(11) NOT NULL, 34 | `width` int(11) NOT NULL, 35 | `materials` varchar(100) NOT NULL, 36 | `price` decimal(6,2) NOT NULL, 37 | `quantity` int(11) NOT NULL, 38 | `available` tinyint(1) NOT NULL DEFAULT '0', 39 | `category_id` int(11) NOT NULL, 40 | PRIMARY KEY (`id`), 41 | UNIQUE KEY `name_UNIQUE` (`name`), 42 | KEY `fk_artworks_category1_idx` (`category_id`), 43 | CONSTRAINT `fk_artworks_category1` FOREIGN KEY (`category_id`) REFERENCES `category` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION 44 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 45 | 46 | CREATE TABLE `sales` ( 47 | `id` int(11) NOT NULL AUTO_INCREMENT, 48 | `artworks_id` int(11) NOT NULL, 49 | `customers_id` int(11) NOT NULL, 50 | `sold_at` datetime NOT NULL, 51 | `sale_price` decimal(6,2) NOT NULL, 52 | `shipped` tinyint(1) NOT NULL DEFAULT '0', 53 | `shipped_at` datetime DEFAULT NULL, 54 | PRIMARY KEY (`id`), 55 | KEY `fk_sales_artworks_idx` (`artworks_id`), 56 | KEY `fk_sales_customers1_idx` (`customers_id`), 57 | CONSTRAINT `fk_sales_artworks` FOREIGN KEY (`artworks_id`) REFERENCES `artworks` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, 58 | CONSTRAINT `fk_sales_customers1` FOREIGN KEY (`customers_id`) REFERENCES `customers` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION 59 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 60 | -------------------------------------------------------------------------------- /clean.sql: -------------------------------------------------------------------------------- 1 | drop database if exists CAVE_TEST; 2 | drop database if exists CAVE_ONLINE_SHOP; 3 | drop database if exists CAVE_HEALTH_SURVEY; 4 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | # This just tests the .sql files 2 | # Warning: it will drop and create a database called 3 | # online_shop 4 | 5 | # Only actually tested on Mac. Might perhaps be got to work 6 | # on Windows if GNU make is installed. 7 | 8 | # Use at your own risk! 9 | 10 | # Usage: make tests 11 | 12 | # Add password (-pPASSWORD) if you need it, 13 | # or change user name (-u USERNAME) 14 | command = mysql -u root 15 | shell = bash -c 16 | 17 | dependencies = \ 18 | Exporting_Data \ 19 | Solutions1 \ 20 | Solutions2 \ 21 | Solutions3 \ 22 | Left_and_Right_Outer_Joins \ 23 | Joins_Between_Pairs_of_Tables \ 24 | Many_to_Many \ 25 | Joining_Tables_to_Themselves \ 26 | Restrict \ 27 | Adding_Columns \ 28 | Adding_Foreign_keys \ 29 | Indexing_Multiple_Columns \ 30 | Views \ 31 | With_Check_Option \ 32 | Demonstrating_Isolation_Levels_and_Row_Locking \ 33 | Date_Functions \ 34 | Control_Flow_Functions \ 35 | Hello_World \ 36 | Out_Parameters \ 37 | Labelled_Loops \ 38 | Generating_Random_Data \ 39 | Fetching_Cursor_Data_With_Loops \ 40 | Case_Expression \ 41 | Solutions4 \ 42 | Introducing_Triggers \ 43 | Triggers_and_Validation \ 44 | Triggers_and_Transactions \ 45 | Solution5 \ 46 | Defining_Functions \ 47 | Art_Shop 48 | 49 | default: 50 | echo "run 'make test'" 51 | echo "Use at your own risk." 52 | echo "Creates and drops databases: CAVE_TEST, CAVE_ONLINE_SHOP, CAVE_ART_SHOP" 53 | echo "Also creates and drops procedures, functions, etc." 54 | echo "Do not run as root user on important database!" 55 | 56 | test: $(dependencies) 57 | echo "Hello"; 58 | 59 | Exporting_Data: clean 60 | $(shell) "$(command) < *$(@).sql" 61 | 62 | Some_Test_Data: clean 63 | $(shell) "$(command) < *$(@).sql" 64 | 65 | Solutions1: Some_Test_Data 66 | $(shell) "$(command) < *$(@).sql" 67 | 68 | Solutions2: Some_Test_Data 69 | $(shell) "$(command) < *$(@).sql" 70 | 71 | Health_Database: clean 72 | $(shell) "$(command) < *$(@).sql" 73 | 74 | Solutions3: Health_Database 75 | $(shell) "$(command) < *$(@).sql" 76 | 77 | Foreign_Keys: clean 78 | $(shell) "$(command) < *$(@).sql" 79 | 80 | Joins_and_Cartesian_Products: Foreign_Keys 81 | $(shell) "$(command) < *$(@).sql" 82 | 83 | Inner_Joins: Joins_and_Cartesian_Products 84 | $(shell) "$(command) < *$(@).sql" 85 | 86 | Left_and_Right_Outer_Joins: Inner_Joins 87 | $(shell) "$(command) < *$(@).sql" 88 | 89 | Joins_Between_Pairs_of_Tables: Health_Database 90 | $(shell) "$(command) < *$(@).sql" 91 | 92 | Many_to_Many: Foreign_Keys 93 | $(shell) "$(command) < *$(@).sql" 94 | 95 | Joining_Tables_to_Themselves: clean 96 | $(shell) "$(command) < *$(@).sql" 97 | 98 | Restrict: clean 99 | $(shell) "$(command) < *$(@).sql" 100 | 101 | Online_Shop: clean 102 | $(shell) "$(command) < *$(@).sql" 103 | 104 | Adding_Columns: clean 105 | $(shell) "$(command) < *$(@).sql" 106 | 107 | Adding_Foreign_keys: clean 108 | $(shell) "$(command) < *$(@).sql" 109 | 110 | Adding_Indexes: clean 111 | $(shell) "$(command) < *$(@).sql" 112 | 113 | Indexing_Multiple_Columns: Adding_Indexes 114 | $(shell) "$(command) < *$(@).sql" 115 | 116 | Views: clean 117 | $(shell) "$(command) < *$(@).sql" 118 | 119 | View_Algorithms: Online_Shop 120 | $(shell) "$(command) < *$(@).sql" 121 | 122 | With_Check_Option: clean 123 | $(shell) "$(command) < *$(@).sql" 124 | 125 | Using_Variables: View_Algorithms 126 | $(shell) "$(command) < *$(@).sql" 127 | 128 | Setting_Variables_With_Selects: Using_Variables 129 | $(shell) "$(command) < *$(@).sql" 130 | 131 | Select_Update_Example: Setting_Variables_With_Selects 132 | $(shell) "$(command) < *$(@).sql" 133 | 134 | Fixing_Select_Update_With_Table_Locks: Select_Update_Example 135 | $(shell) "$(command) < *$(@).sql" 136 | 137 | A_Simple_Transaction: clean 138 | $(shell) "$(command) < *$(@).sql" 139 | 140 | Demonstrating_Isolation_Levels_and_Row_Locking: A_Simple_Transaction 141 | $(shell) "$(command) < *$(@).sql" 142 | 143 | Select_for_Update: clean 144 | $(shell) "$(command) < *$(@).sql" 145 | 146 | Lock_in_Share_Mode: clean 147 | $(shell) "$(command) < *$(@).sql" 148 | 149 | String_functions: Lock_in_Share_Mode 150 | $(shell) "$(command) < *$(@).sql" 151 | 152 | Date_Functions: clean 153 | $(shell) "$(command) < *$(@).sql" 154 | 155 | Control_Flow_Functions: clean 156 | $(shell) "$(command) < *$(@).sql" 157 | 158 | Casting: String_functions 159 | $(shell) "$(command) < *$(@).sql" 160 | 161 | Hello_World: clean 162 | $(shell) "$(command) < *$(@).sql" 163 | 164 | Setting_the_Definer: Fixing_Select_Update_With_Table_Locks 165 | $(shell) "$(command) < *$(@).sql" 166 | 167 | Procedure_Permission_Example: Setting_the_Definer 168 | $(shell) "$(command) < *$(@).sql" 169 | 170 | Procedure_Permissions: Procedure_Permission_Example 171 | $(shell) "$(command) < *$(@).sql" 172 | 173 | Passing_Parameters: Casting 174 | $(shell) "$(command) < *$(@).sql" 175 | 176 | Out_Parameters: Passing_Parameters 177 | $(shell) "$(command) < *$(@).sql" 178 | 179 | If: Select_for_Update 180 | $(shell) "$(command) < *$(@).sql" 181 | 182 | Local_Variables: If 183 | $(shell) "$(command) < *$(@).sql" 184 | 185 | Account_Withdrawal: Local_Variables 186 | $(shell) "$(command) < *$(@).sql" 187 | 188 | Transactional_Withdrawal: Account_Withdrawal 189 | $(shell) "$(command) < *$(@).sql" 190 | 191 | Error_Handlers: Transactional_Withdrawal 192 | $(shell) "$(command) < *$(@).sql" 193 | 194 | While_Loops: Error_Handlers 195 | $(shell) "$(command) < *$(@).sql" 196 | 197 | Labelled_Loops: While_Loops 198 | $(shell) "$(command) < *$(@).sql" 199 | 200 | Generating_Random_Data: clean 201 | $(shell) "$(command) < *$(@).sql" 202 | 203 | A_Data_Generating_Procedure: clean 204 | $(shell) "$(command) < *$(@).sql" 205 | 206 | Cursors: A_Data_Generating_Procedure 207 | $(shell) "$(command) < *$(@).sql" 208 | 209 | Fetching_Cursor_Data_With_Loops: Cursors 210 | $(shell) "$(command) < *$(@).sql" 211 | 212 | Case_Expression: clean 213 | $(shell) "$(command) < *$(@).sql" 214 | 215 | Solutions4: clean 216 | $(shell) "$(command) < *$(@).sql" 217 | 218 | Introducing_Triggers: clean 219 | $(shell) "$(command) < *$(@).sql" 220 | 221 | Triggers_and_Validation: clean 222 | $(shell) "$(command) < *$(@).sql" 223 | 224 | Triggers_and_Transactions: clean 225 | $(shell) "$(command) < *$(@).sql" 226 | 227 | Solution5: clean 228 | $(shell) "$(command) < *$(@).sql" 229 | 230 | Defining_Functions: Procedure_Permissions 231 | $(shell) "$(command) < *$(@).sql" 232 | 233 | Art_Shop: clean 234 | $(shell) "$(command) < *$(@).sql" 235 | 236 | 237 | clean: 238 | $(shell) "$(command) < clean.sql" 239 | 240 | # $(command) < 241 | -------------------------------------------------------------------------------- /out.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caveofprogramming/mysql-course/7f89db23f6aff1b31a9389e17308aab8e74ef4d6/out.png --------------------------------------------------------------------------------