diff --git a/Databases/flights.db b/Databases/flights.db new file mode 100644 index 0000000..e69de29 diff --git a/Databases/flights.sqlite3 b/Databases/flights.sqlite3 new file mode 100644 index 0000000..2291210 Binary files /dev/null and b/Databases/flights.sqlite3 differ diff --git a/Databases/pets.sqlite3 b/Databases/pets.sqlite3 new file mode 100644 index 0000000..caa8596 Binary files /dev/null and b/Databases/pets.sqlite3 differ diff --git a/Databases/population.sqlite3 b/Databases/population.sqlite3 new file mode 100644 index 0000000..944dab0 Binary files /dev/null and b/Databases/population.sqlite3 differ diff --git a/Databases/public_pets_sqlite.sql b/Databases/public_pets_sqlite.sql new file mode 100644 index 0000000..432a84a --- /dev/null +++ b/Databases/public_pets_sqlite.sql @@ -0,0 +1,69 @@ +PRAGMA synchronous = OFF; +PRAGMA journal_mode = MEMORY; +BEGIN TRANSACTION; +CREATE TABLE "BREED" ( + "BreedName" varchar(100) NOT NULL, + "MinWeight" decimal(4,1) DEFAULT NULL, + "MaxWeight" decimal(4,1) DEFAULT NULL, + "AverageLifeExpectancy" decimal(4,1) DEFAULT NULL, + PRIMARY KEY ("BreedName") +); +INSERT INTO "BREED" VALUES ('Border Collie',15.0,22.5,20.0); +INSERT INTO "BREED" VALUES ('Cashmere',10.0,15.0,12.0); +INSERT INTO "BREED" VALUES ('Collie Mix',17.5,25.0,18.0); +INSERT INTO "BREED" VALUES ('Std. Poodle',22.5,30.0,18.0); +INSERT INTO "BREED" VALUES ('Unknown',NULL,NULL,NULL); +CREATE TABLE "PET" ( + "PetID" int(11) NOT NULL , + "PetName" char(50) NOT NULL, + "PetType" char(25) NOT NULL, + "PetBreed" varchar(100) DEFAULT NULL, + "PetDOB" date DEFAULT NULL, + "OwnerID" int(11) NOT NULL, + PRIMARY KEY ("PetID") + CONSTRAINT "PET_BREED_FK" FOREIGN KEY ("PetBreed") REFERENCES "BREED" ("BreedName") ON UPDATE CASCADE, + CONSTRAINT "PET_OWNER_FK" FOREIGN KEY ("OwnerID") REFERENCES "PET_OWNER" ("OwnerID") ON DELETE CASCADE +); +INSERT INTO "PET" VALUES (1,'King','Dog','Std. Poodle','2011-02-27',1); +INSERT INTO "PET" VALUES (2,'Teddy','Cat','Cashmere','2012-02-01',2); +INSERT INTO "PET" VALUES (3,'Fido','Dog','Std. Poodle','2010-07-17',1); +INSERT INTO "PET" VALUES (4,'AJ','Dog','Collie Mix','2011-05-05',3); +INSERT INTO "PET" VALUES (5,'Cedro','Cat',NULL,'2009-06-06',2); +INSERT INTO "PET" VALUES (6,'Wooley','Cat',NULL,NULL,2); +INSERT INTO "PET" VALUES (7,'Buster','Dog','Border Collie','2008-12-11',4); +CREATE TABLE "PET_3" ( + "PetID" int(11) NOT NULL , + "PetName" char(50) NOT NULL, + "PetType" char(25) NOT NULL, + "PetBreed" varchar(100) DEFAULT NULL, + "PetDOB" date DEFAULT NULL, + "PetWeight" decimal(4,1) DEFAULT NULL, + "OwnerID" int(11) NOT NULL, + PRIMARY KEY ("PetID") + CONSTRAINT "PET_3_BREED_FK" FOREIGN KEY ("PetBreed") REFERENCES "BREED" ("BreedName") ON UPDATE CASCADE, + CONSTRAINT "PET_3_OWNER_FK" FOREIGN KEY ("OwnerID") REFERENCES "PET_OWNER" ("OwnerID") ON DELETE CASCADE +); +INSERT INTO "PET_3" VALUES (1,'King','Dog','Std. Poodle','2011-02-27',25.5,1); +INSERT INTO "PET_3" VALUES (2,'Teddy','Cat','Cashmere','2012-02-01',10.5,2); +INSERT INTO "PET_3" VALUES (3,'Fido','Dog','Std. Poodle','2010-07-17',28.5,1); +INSERT INTO "PET_3" VALUES (4,'AJ','Dog','Collie Mix','2011-05-05',20.0,3); +INSERT INTO "PET_3" VALUES (5,'Cedro','Cat',NULL,'2009-06-06',9.5,2); +INSERT INTO "PET_3" VALUES (6,'Wooley','Cat',NULL,NULL,9.5,2); +INSERT INTO "PET_3" VALUES (7,'Buster','Dog','Border Collie','2008-12-11',25.0,4); +CREATE TABLE "PET_OWNER" ( + "OwnerID" int(11) NOT NULL , + "OwnerLastName" char(25) NOT NULL, + "OwnerFirstName" char(25) NOT NULL, + "OwnerPhone" char(12) DEFAULT NULL, + "OwnerEmail" varchar(100) DEFAULT NULL, + PRIMARY KEY ("OwnerID") +); +INSERT INTO "PET_OWNER" VALUES (1,'Downs','Marsha','555-537-8765','Marsha.Downs@somewhere.com'); +INSERT INTO "PET_OWNER" VALUES (2,'James','Richard','555-537-7654','Richard.James@somewhere.com'); +INSERT INTO "PET_OWNER" VALUES (3,'Frier','Liz','555-537-6543','Liz.Frier@somewhere.com'); +INSERT INTO "PET_OWNER" VALUES (4,'Trent','Miles',NULL,'Miles.Trent@somewhere.com'); +CREATE INDEX "PET_3_PET_3_OWNER_FK" ON "PET_3" ("OwnerID"); +CREATE INDEX "PET_3_PET_3_BREED_FK" ON "PET_3" ("PetBreed"); +CREATE INDEX "PET_PET_OWNER_FK" ON "PET" ("OwnerID"); +CREATE INDEX "PET_PET_BREED_FK" ON "PET" ("PetBreed"); +END TRANSACTION; diff --git a/Databases/queen_anne.sqlite3 b/Databases/queen_anne.sqlite3 new file mode 100644 index 0000000..fdf907f Binary files /dev/null and b/Databases/queen_anne.sqlite3 differ diff --git a/Databases/queen_anne_sqlite.sql b/Databases/queen_anne_sqlite.sql new file mode 100644 index 0000000..2556c6c --- /dev/null +++ b/Databases/queen_anne_sqlite.sql @@ -0,0 +1,160 @@ +PRAGMA synchronous = OFF; +PRAGMA journal_mode = MEMORY; +BEGIN TRANSACTION; + +CREATE TABLE "CUSTOMER" ( + "CustomerID" int(11) NOT NULL , + "LastName" char(25) NOT NULL, + "FirstName" char(25) NOT NULL, + "Address" char(35) DEFAULT NULL, + "City" char(35) DEFAULT NULL, + "State" char(2) DEFAULT NULL, + "ZIP" char(10) DEFAULT NULL, + "Phone" char(12) NOT NULL, + "Email" varchar(100) DEFAULT NULL, + PRIMARY KEY ("CustomerID") +); +INSERT INTO "CUSTOMER" VALUES (1,'Shire','Robert','6225 Evanston Ave N','Seattle','WA','98103','206-524-2433','Robert.Shire@somewhere.com'); +INSERT INTO "CUSTOMER" VALUES (2,'Goodyear','Katherine','7335 11th Ave NE','Seattle','WA','98105','206-524-3544','Katherine.Goodyear@somewhere.com'); +INSERT INTO "CUSTOMER" VALUES (3,'Bancroft','Chris','12605 NE 6th Street','Bellevue','WA','98005','425-635-9788','Chris.Bancroft@somewhere.com'); +INSERT INTO "CUSTOMER" VALUES (4,'Griffith','John','335 Aloha Street','Seattle','WA','98109','206-524-4655','John.Griffith@somewhere.com'); +INSERT INTO "CUSTOMER" VALUES (5,'Tierney','Doris','14510 NE 4th Street','Bellevue','WA','98005','425-635-8677','Doris.Tierney@somewhere.com'); +INSERT INTO "CUSTOMER" VALUES (6,'Anderson','Donna','1410 Hillcrest Parkway','Mt. Vernon','WA','98273','360-538-7566','Donna.Anderson@elsewhere.com'); +INSERT INTO "CUSTOMER" VALUES (7,'Svane','Jack','3211 42nd Street','Seattle','WA','98115','206-524-5766','Jack.Svane@somewhere.com'); +INSERT INTO "CUSTOMER" VALUES (8,'Walsh','Denesha','6712 24th Avenue NE','Redmond','WA','98053','425-635-7566','Denesha.Walsh@somewhere.com'); +INSERT INTO "CUSTOMER" VALUES (9,'Enquist','Craig','534 15th Street','Bellingham','WA','98225','360-538-6455','Craig.Enquist@elsewhere.com'); +INSERT INTO "CUSTOMER" VALUES (10,'Anderson','Rose','6823 17th Ave NE','Seattle','WA','98105','206-524-6877','Rose.Anderson@elsewhere.com'); +CREATE TABLE "EMPLOYEE" ( + "EmployeeID" int(11) NOT NULL , + "LastName" char(25) NOT NULL, + "FirstName" char(25) NOT NULL, + "Phone" char(12) DEFAULT NULL, + "Email" varchar(100) NOT NULL, + PRIMARY KEY ("EmployeeID") +); +INSERT INTO "EMPLOYEE" VALUES (1,'Stuart','Anne','206-527-0010','Anne.Stuart@QACS.com'); +INSERT INTO "EMPLOYEE" VALUES (2,'Stuart','George','206-527-0011','George.Stuart@QACS.com'); +INSERT INTO "EMPLOYEE" VALUES (3,'Stuart','Mary','206-527-0012','Mary.Stuart@QACS.com'); +INSERT INTO "EMPLOYEE" VALUES (4,'Orange','William','206-527-0013','William.Orange@QACS.com'); +INSERT INTO "EMPLOYEE" VALUES (5,'Griffith','John','206-527-0014','John.Griffith@QACS.com'); +CREATE TABLE "ITEM" ( + "ItemID" int(11) NOT NULL , + "ItemDescription" varchar(255) NOT NULL, + "PurchaseDate" datetime NOT NULL, + "ItemCost" decimal(9,2) NOT NULL, + "ItemPrice" decimal(9,2) NOT NULL, + "VendorID" int(11) NOT NULL, + PRIMARY KEY ("ItemID") + CONSTRAINT "ITEM_VENDOR_FK" FOREIGN KEY ("VendorID") REFERENCES "VENDOR" ("VendorID") ON DELETE NO ACTION ON UPDATE NO ACTION +); +INSERT INTO "ITEM" VALUES (1,'Antique Desk','2013-11-07 00:00:00',1800.00,3000.00,2); +INSERT INTO "ITEM" VALUES (2,'Antique Desk Chair','2013-11-10 00:00:00',300.00,500.00,4); +INSERT INTO "ITEM" VALUES (3,'Dining Table Linens','2013-11-14 00:00:00',600.00,1000.00,1); +INSERT INTO "ITEM" VALUES (4,'Candles','2013-11-14 00:00:00',30.00,50.00,1); +INSERT INTO "ITEM" VALUES (5,'Candles','2013-11-14 00:00:00',27.00,45.00,1); +INSERT INTO "ITEM" VALUES (6,'Desk Lamp','2013-11-14 00:00:00',150.00,250.00,3); +INSERT INTO "ITEM" VALUES (7,'Dining Table Linens','2013-11-14 00:00:00',450.00,750.00,1); +INSERT INTO "ITEM" VALUES (8,'Book Shelf','2013-11-21 00:00:00',150.00,250.00,5); +INSERT INTO "ITEM" VALUES (9,'Antique Chair','2013-11-21 00:00:00',750.00,1250.00,6); +INSERT INTO "ITEM" VALUES (10,'Antique Chair','2013-11-21 00:00:00',1050.00,1750.00,6); +INSERT INTO "ITEM" VALUES (11,'Antique Candle Holders','2013-11-28 00:00:00',210.00,350.00,2); +INSERT INTO "ITEM" VALUES (12,'Antique Desk','2014-01-05 00:00:00',1920.00,3200.00,2); +INSERT INTO "ITEM" VALUES (13,'Antique Desk','2014-01-05 00:00:00',2100.00,3500.00,2); +INSERT INTO "ITEM" VALUES (14,'Antique Desk Chair','2014-01-06 00:00:00',285.00,475.00,9); +INSERT INTO "ITEM" VALUES (15,'Antique Desk Chair','2014-01-06 00:00:00',339.00,565.00,9); +INSERT INTO "ITEM" VALUES (16,'Desk Lamp','2014-01-06 00:00:00',150.00,250.00,10); +INSERT INTO "ITEM" VALUES (17,'Desk Lamp','2014-01-06 00:00:00',150.00,250.00,10); +INSERT INTO "ITEM" VALUES (18,'Desk Lamp','2014-01-06 00:00:00',144.00,240.00,3); +INSERT INTO "ITEM" VALUES (19,'Antique Dining Table','2014-01-10 00:00:00',3000.00,5000.00,7); +INSERT INTO "ITEM" VALUES (20,'Antique Sideboard','2014-01-11 00:00:00',2700.00,4500.00,8); +INSERT INTO "ITEM" VALUES (21,'Dining Table Chairs','2014-01-11 00:00:00',5100.00,8500.00,9); +INSERT INTO "ITEM" VALUES (22,'Dining Table Linens','2014-01-12 00:00:00',450.00,750.00,1); +INSERT INTO "ITEM" VALUES (23,'Dining Table Linens','2014-01-12 00:00:00',480.00,800.00,1); +INSERT INTO "ITEM" VALUES (24,'Candles','2014-01-17 00:00:00',30.00,50.00,1); +INSERT INTO "ITEM" VALUES (25,'Candles','2014-01-17 00:00:00',36.00,60.00,1); +CREATE TABLE "SALE" ( + "SaleID" int(11) NOT NULL , + "CustomerID" int(11) NOT NULL, + "EmployeeID" int(11) NOT NULL, + "SaleDate" datetime NOT NULL, + "SubTotal" decimal(15,2) DEFAULT NULL, + "Tax" decimal(15,2) DEFAULT NULL, + "Total" decimal(15,2) DEFAULT NULL, + PRIMARY KEY ("SaleID") + CONSTRAINT "SALE_CUSTOMER_FK" FOREIGN KEY ("CustomerID") REFERENCES "CUSTOMER" ("CustomerID") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "SALE_EMPLOYEE_FK" FOREIGN KEY ("EmployeeID") REFERENCES "EMPLOYEE" ("EmployeeID") ON DELETE NO ACTION ON UPDATE NO ACTION +); +INSERT INTO "SALE" VALUES (1,1,1,'2013-12-14 00:00:00',3500.00,290.50,3790.50); +INSERT INTO "SALE" VALUES (2,2,1,'2013-12-15 00:00:00',1000.00,83.00,1083.00); +INSERT INTO "SALE" VALUES (3,3,1,'2013-12-15 00:00:00',50.00,4.15,54.15); +INSERT INTO "SALE" VALUES (4,4,3,'2013-12-23 00:00:00',45.00,3.74,48.74); +INSERT INTO "SALE" VALUES (5,1,5,'2014-01-05 00:00:00',250.00,20.75,270.75); +INSERT INTO "SALE" VALUES (6,5,5,'2014-01-10 00:00:00',750.00,62.25,812.25); +INSERT INTO "SALE" VALUES (7,6,4,'2014-01-12 00:00:00',250.00,20.75,270.75); +INSERT INTO "SALE" VALUES (8,2,1,'2014-01-15 00:00:00',3000.00,249.00,3249.00); +INSERT INTO "SALE" VALUES (9,5,5,'2014-01-25 00:00:00',350.00,29.05,379.05); +INSERT INTO "SALE" VALUES (10,7,1,'2014-02-04 00:00:00',14250.00,1182.75,15432.75); +INSERT INTO "SALE" VALUES (11,8,5,'2014-02-04 00:00:00',250.00,20.75,270.75); +INSERT INTO "SALE" VALUES (12,5,4,'2014-02-07 00:00:00',50.00,4.15,54.15); +INSERT INTO "SALE" VALUES (13,9,2,'2014-02-07 00:00:00',4500.00,373.50,4873.50); +INSERT INTO "SALE" VALUES (14,10,3,'2014-02-11 00:00:00',3675.00,305.03,3980.03); +INSERT INTO "SALE" VALUES (15,2,2,'2014-02-11 00:00:00',800.00,66.40,866.40); +CREATE TABLE "SALE_ITEM" ( + "SaleID" int(11) NOT NULL, + "SaleItemID" int(11) NOT NULL, + "ItemID" int(11) NOT NULL, + "ItemPrice" decimal(9,2) NOT NULL, + PRIMARY KEY ("SaleID","SaleItemID") + CONSTRAINT "SALE_ITEM_ITEM_FK" FOREIGN KEY ("ItemID") REFERENCES "ITEM" ("ItemID") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "SALE_ITEM_SALE_FK" FOREIGN KEY ("SaleID") REFERENCES "SALE" ("SaleID") ON DELETE CASCADE ON UPDATE NO ACTION +); +INSERT INTO "SALE_ITEM" VALUES (1,1,1,3000.00); +INSERT INTO "SALE_ITEM" VALUES (1,2,2,500.00); +INSERT INTO "SALE_ITEM" VALUES (2,1,3,1000.00); +INSERT INTO "SALE_ITEM" VALUES (3,1,4,50.00); +INSERT INTO "SALE_ITEM" VALUES (4,1,5,45.00); +INSERT INTO "SALE_ITEM" VALUES (5,1,6,250.00); +INSERT INTO "SALE_ITEM" VALUES (6,1,7,750.00); +INSERT INTO "SALE_ITEM" VALUES (7,1,8,250.00); +INSERT INTO "SALE_ITEM" VALUES (8,1,9,1250.00); +INSERT INTO "SALE_ITEM" VALUES (8,2,10,1750.00); +INSERT INTO "SALE_ITEM" VALUES (9,1,11,350.00); +INSERT INTO "SALE_ITEM" VALUES (10,1,19,5000.00); +INSERT INTO "SALE_ITEM" VALUES (10,2,21,8500.00); +INSERT INTO "SALE_ITEM" VALUES (10,3,22,750.00); +INSERT INTO "SALE_ITEM" VALUES (11,1,17,250.00); +INSERT INTO "SALE_ITEM" VALUES (12,1,24,50.00); +INSERT INTO "SALE_ITEM" VALUES (13,1,20,4500.00); +INSERT INTO "SALE_ITEM" VALUES (14,1,12,3200.00); +INSERT INTO "SALE_ITEM" VALUES (14,2,14,475.00); +INSERT INTO "SALE_ITEM" VALUES (15,1,23,800.00); +CREATE TABLE "VENDOR" ( + "VendorID" int(11) NOT NULL , + "CompanyName" char(100) DEFAULT NULL, + "ContactLastName" char(25) NOT NULL, + "ContactFirstName" char(25) NOT NULL, + "Address" char(35) DEFAULT NULL, + "City" char(35) DEFAULT NULL, + "State" char(2) DEFAULT NULL, + "ZIP" char(10) DEFAULT NULL, + "Phone" char(12) NOT NULL, + "Fax" char(12) DEFAULT NULL, + "Email" varchar(100) DEFAULT NULL, + PRIMARY KEY ("VendorID") +); +INSERT INTO "VENDOR" VALUES (1,'Linens and Things','Huntington','Anne','1515 NW Market Street','Seattle','WA','98107','206-325-6755','206-329-9675','LAT@business.com'); +INSERT INTO "VENDOR" VALUES (2,'European Specialties','Tadema','Ken','6123 15th Avenue NW','Seattle','WA','98107','206-325-7866','206-329-9786','ES@business.com'); +INSERT INTO "VENDOR" VALUES (3,'Lamps and Lighting','Swanson','Sally','506 Prospect Street','Seattle','WA','98109','206-325-8977','206-329-9897','LAL@business.com'); +INSERT INTO "VENDOR" VALUES (4,NULL,'Lee','Andrew','1102 3rd Street','Kirkland','WA','98033','425-746-5433',NULL,'Andrew.Lee@somewhere.com'); +INSERT INTO "VENDOR" VALUES (5,NULL,'Harrison','Denise','533 10th Avenue','Kirkland','WA','98033','425-746-4322',NULL,'Denise.Harrison@somewhere.com'); +INSERT INTO "VENDOR" VALUES (6,'New York Brokerage','Smith','Mark','621 Roy Street','Seattle','WA','98109','206-325-9088','206-329-9908','NYB@business.com'); +INSERT INTO "VENDOR" VALUES (7,NULL,'Walsh','Denesha','6712 24th Avenue NE','Redmond','WA','98053','425-635-7566',NULL,'Denesha.Walsh@somewhere.com'); +INSERT INTO "VENDOR" VALUES (8,NULL,'Bancroft','Chris','12605 NE 6th Street','Bellevue','WA','98005','425-635-9788','425-639-9978','Chris.Bancroft@somewhere.com'); +INSERT INTO "VENDOR" VALUES (9,'Specialty Antiques','Nelson','Fred','2512 Lucky Street','San Francisco','CA','94110','415-422-2121','415-429-9212','SA@business.com'); +INSERT INTO "VENDOR" VALUES (10,'General Antiques','Garner','Patty','2515 Lucky Street','San Francisco','CA','94110','415-422-3232','415-429-9323','GA@business.com'); +CREATE INDEX "SALE_ITEM_SALE_ITEM_ITEM_FK" ON "SALE_ITEM" ("ItemID"); +CREATE INDEX "SALE_SALE_CUSTOMER_FK" ON "SALE" ("CustomerID"); +CREATE INDEX "SALE_SALE_EMPLOYEE_FK" ON "SALE" ("EmployeeID"); +CREATE INDEX "EMPLOYEE_Email" ON "EMPLOYEE" ("Email"); +CREATE INDEX "ITEM_ITEM_VENDOR_FK" ON "ITEM" ("VendorID"); +END TRANSACTION; diff --git a/Week01/airport_search.ipynb b/Week01/airport_search.ipynb new file mode 100644 index 0000000..b42d422 --- /dev/null +++ b/Week01/airport_search.ipynb @@ -0,0 +1,86 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from ipywidgets import interact, interactive, fixed, interact_manual\n", + "import ipywidgets as widgets\n", + "import sqlite3\n", + "from mpl_toolkits.basemap import Basemap\n", + "import matplotlib.pyplot as plt\n", + "\n", + "@interact(country='United States')\n", + "def draw_map(country):\n", + " plt.rcParams['figure.figsize'] = [10, 10]\n", + " conn = sqlite3.connect(\"flights.db\")\n", + " cur = conn.cursor()\n", + " coords = cur.execute(f\"\"\"\n", + " select longitude, latitude \n", + " from airports where country = '{country}';\"\"\"\n", + " ).fetchall()\n", + "\n", + " m = Basemap(\n", + " projection='merc',\n", + " llcrnrlat=-80,\n", + " urcrnrlat=80,\n", + " llcrnrlon=-180,\n", + " urcrnrlon=180,\n", + " lat_ts=20,\n", + " resolution='c', \n", + " )\n", + "\n", + " m.drawcoastlines()\n", + " m.drawmapboundary()\n", + "\n", + " x, y = m(\n", + " [float(l[0]) for l in coords], \n", + " [float(l[1]) for l in coords]\n", + " )\n", + "\n", + " m.scatter(\n", + " x,\n", + " y,\n", + " 1,\n", + " marker='o',\n", + " color='red'\n", + " )\n", + "\n", + " cur.close()\n", + " conn.close()\n", + "\n", + " return m\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Week01/flights.db b/Week01/flights.db new file mode 100644 index 0000000..5f8e2ba Binary files /dev/null and b/Week01/flights.db differ diff --git a/Week02/query_airports_with_sql.ipynb b/Week02/query_airports_with_sql.ipynb new file mode 100644 index 0000000..ffa1340 --- /dev/null +++ b/Week02/query_airports_with_sql.ipynb @@ -0,0 +1,139 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# SQL Queries in Notebooks\n", + "\n", + "Jupyter has the ability to mix different types of program code in a notebook. The class notebooks default to Python. However, SQL can be accomplised by adding so-called [cell magics](https://ipython.readthedocs.io/en/stable/interactive/magics.html). This notebooks shows you how to setup cell magics to use SQL.\n", + "\n", + "The cell below enables the SQL extension to Jupyter." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext sql" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `%load_ext sql` only needs to run once. If you re-run it a warning is shown. It's okay to ignore the warning. The next cell creates a connection to the DBMS. Jupyter is capable of accessing every popular DBMS this way. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%sql sqlite:///../Week01/flights.db " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Running this cell should produce a message that says `Connected: ...`. In this workbook we're using [SQLite](https://www.sqlite.org/index.html). SQLite is an *embedded* DBMS. Instead of using the client/server model that we're using on killgrave, the database is located in the `flights.db` file. SQLite is very, very convenient but doesn't scale as well as MySQL and the other client/server DBMSes. \n", + "\n", + "A cell that contains the `%%sql` magic is expected to contain SQL queries for the connected datbase. For example, here's an SQL query that shows all of the airports in New Zealand:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n", + "select * from airports where country = 'New Zealand';" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Exercises \n", + "\n", + "You don't need to know any SQL at this point in the class, but these exercises will get you warmed up. Start by copying the SQL query from the cell above, paste it into the SQL cells below this one. Your challenge is to modify the queries so that they produce the requested data. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### What are the airports in Sweden? \n", + "\n", + "Modify the SQL query to search in Sweden instead of New Zealand." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n", + "select * from airports where country = 'Sweden';" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### What are the airports in San Jose? \n", + "\n", + "Modify the query to search for the city of San Jose instead of the country of New Zealand? " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n", + "select * from airports where city = 'San Jose';" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Turn In \n", + "\n", + "Zip the contents of the Week02 folder and turn it in on Canvas" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Week06/.simple_selects.py b/Week06/.simple_selects.py new file mode 100644 index 0000000..4f02d0c --- /dev/null +++ b/Week06/.simple_selects.py @@ -0,0 +1,212 @@ +""" +CIS-54 Course SQL Questions +""" + +import sys +import inspect + +from IPython.display import HTML, Markdown, display +import sqlite3 +import pandas as pd + +conn = sqlite3.connect('../Databases/flights.sqlite3') + +class Question01: + """ +## 1. Select Airports + +Write an SQL query that selects all rows from the `airports` table. + """ + answer = "select * from airports limit 5;" + +class Question02: + """ +## 2. Select Airlines + +Write an SQL query that selects all rows from the `airlines` table. + """ + answer = "select * from airlines limit 5;" + +class Question03: + """ +## 3. Select Routes + +Write an SQL query that selects all rows from the `routes` table. + """ + answer = "select * from routes limit 5;" + +class Question04: + """ +## 4. Select Specific Columns + +Write an SQL query that selects the following columns from the `airports` table. + + - code + """ + + answer = 'select code from airports limit 5;' + +class Question05: + """ +## 5. Select Specific Columns + +Write an SQL query that selects the following columns from the `airports` table. + + - code + - city + """ + + answer = 'select code, city from airports limit 5;' + +class Question06: + """ +## 6. Select Specific Columns + +Write an SQL query that selects the following columns from the `airports` table. + + - code + - city + - latitude + - longitude + + """ + + answer = 'select code, city, latitude, longitude from airports limit 5;' + +class Question07: + """ +## 7. Airports in South Africa + +Write a query that shows every airport in South Africa + """ + answer = "select * from airports where country = 'South Africa' limit 5;" + +class Question08: + """ +## 8. Airports in Springfield + +Write a query that shows every airport in a city called Springfield + """ + answer = "select * from airports where city = 'Springfield' limit 5;" + +class Question09: + """ +## 9. Mile High Airports + +Write a query that shows every airport that has an altitude higher than 5,200 feet. + """ + answer = "select * from airports where altitude > 5200 limit 5" + +class Question10: + """ +## 10. Airports Ending in X + +Write a query that shows every airport that has a three-letter code ending in 'X'. + """ + answer = "select * from airports where code like '__X' limit 5" + +class Question11: + """ +## 11. High Airports Ending in X + +Write a query that shows every airport that has a three-letter code ending in +'X' **and** has an altitude of greater than 5,200 feet. + """ + answer = "select * from airports where code like '__X' and altitude > 5200 limit 5" + +class Question12: + """ +## 12. Equatorial Airports + +Write a query that shows every airport that has has a latitude 5 degrees from the +equator (latitude is less than 5 and greater than -5). + """ + answer = "select * from airports where latitude < 5 and latitude > -5 limit 5" + +class Question13: + """ +## 13. Polar Airports + +Write a query that shows every airport that has has a latitude above or below 80 degrees. + """ + answer = "select * from airports where latitude > 80 or latitude < -80 limit 5" + +class Question14: + """ +## 14. Airlines Without a Callsign + +Write a query that shows every airline with a callsign that is not 'None' + """ + answer = "select * from airlines where callsign <> 'None' limit 5" + +class Question15: + """ +## 15. Foreign San Joses + +Write a query that shows airports in a city called San Jose that are **not** in the United States + """ + answer = "select * from airports where city = 'San Jose' and not country = 'United States' limit 5" + +class Question16: + """ +## 16. Countries with Airports + +Write a query that shows the distinct countries in the airports table. + """ + answer = "select distinct(country) from airports limit 5" + +class Question17: + """ +## 17. Types of Planes + +Write a query that shows planes (equipment) listed in the routes table. + """ + answer = "select distinct(equipment) from routes limit 5" + +class Question18: + """ +## 18. Planes from LAX + +Write a query that shows planes (equipment) that fly from LAX. + """ + answer = "select distinct(equipment) from routes where source = 'LAX' limit 5" + +class Question19: + """ +## 19. Planes to or from LAX + +Write a query that shows planes (equipment) that flies to or from LAX. + """ + answer = "select distinct(equipment) from routes where source = 'LAX' or dest = 'LAX' limit 5" + +class Question20: + """ +## 20. Low Airport Countries + +Write a query that shows countries that have an airport below sea level. + """ + answer = "select distinct(country) from airports where altitude < 0 limit 5" + +q_num = 0 + +def get_question(module, name=None): + global q_num + if name is None: + questions = [] + for name, member in inspect.getmembers(module): + if inspect.isclass(member) and name.startswith('Question'): + questions.append(member) + question = questions[q_num] + q_num += 1 + + else: + question = getattr(module, name) + + hint = '*This sample is limited to five rows.*' + df = pd.read_sql_query(question.answer, conn) + + return display(Markdown(question.__doc__), df, Markdown(hint)) + +if __name__ == '__main__': + get_question(sys.modules[__name__], 'Question1') + \ No newline at end of file diff --git a/Week06/__pycache__/.simple_selects.cpython-36.pyc b/Week06/__pycache__/.simple_selects.cpython-36.pyc new file mode 100644 index 0000000..c6fff87 Binary files /dev/null and b/Week06/__pycache__/.simple_selects.cpython-36.pyc differ diff --git a/Week06/practice_selects.ipynb b/Week06/practice_selects.ipynb new file mode 100644 index 0000000..9b1a0f9 --- /dev/null +++ b/Week06/practice_selects.ipynb @@ -0,0 +1,433 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext sql\n", + "%config SqlMagic.autolimit=100\n", + "%sql sqlite:///../Databases/flights.sqlite3\n", + "\n", + "from course import problem_set\n", + "problem_set.load_file('.simple_selects.py')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Week07/.airports_practice.py b/Week07/.airports_practice.py new file mode 100644 index 0000000..a909b58 --- /dev/null +++ b/Week07/.airports_practice.py @@ -0,0 +1,124 @@ +""" +CIS-54 Course SQL Questions +""" + +import sys +import inspect + +from IPython.display import HTML, Markdown, display +import sqlite3 +import pandas as pd + +conn = sqlite3.connect('../Databases/flights.sqlite3') + +class Question01: + """ +## Highest Airports + +Write a query that lists all airports in order from lowest to highest. +""" + answer = "select * from airports order by altitude limit 5" + +class Question02: + """ +## Lowest Airports + +Write a query that lists all airports in order from highest to lowest. +""" + answer = "select * from airports order by altitude desc limit 5" + +class Question03: + """ +## Highest Airport + +Write a query that returns just one row: The row with the highest airport. +""" + answer = "select * from airports order by altitude limit 1" + +class Question04: + """ +## Count Airports + +Write a query that counts the number of airports in the `airports` table. +""" + answer = "select count(*) as count from airports;" + +class Question05: + """ +## Airlines Without an ICAO Call Sign + +Write a query that shows the airlines without an ICAO Call Sign (where icao is Null) + +> Note: Null values appear as "None" in Jupyter's output. +""" + answer = """select * from airlines where icao is Null limit 5;""" + +class Question06: + """ +## Rename Columns + +Select all routes from the `routes` table. Your output should have the following output columns: + + 1. airline -> rename to "Airline" + 2. source -> rename to "Departs" + 3. dest -> rename to "Arrives" +""" + answer = """select airline as Airline, source as Departs, dest as Arrives from routes limit 5;""" + +class Question07: + """ +## Average Altitude + +Write a query that finds the average altitude of all airports. +""" + answer = """select avg(altitude) as Average from airports;""" + +class Question08: + """ +## Average Altitude of U.S. Airports + +Write a query that finds the average altitude of all airports in the united states. +""" + answer = """select avg(altitude) as Average from airports where country = 'United States';""" + +class Question09: + """ +## Average Altitude by Country + +Write a query that lists all countries and the average altitude of all of the airports in that country. +""" + answer = """select country, avg(altitude) as `average altitude` from airports group by country limit 5;""" + +class Question10: + """ +## Mile High Countries + +Write a query that lists the countries with an average airport altidue of over 5,200 feet. +""" + answer = """select country, avg(altitude) as `average altitude` from airports group by country having avg(altitude) > 5200 limit 5;""" + + +########################################### +q_num = 0 + +def get_question(module, name=None): + global q_num + if name is None: + questions = [] + for name, member in inspect.getmembers(module): + if inspect.isclass(member) and name.startswith('Question'): + questions.append(member) + question = questions[q_num] + q_num += 1 + + else: + question = getattr(module, name) + + hint = '*This preview is limited to five rows.*' + df = pd.read_sql_query(question.answer, conn) + + return display(Markdown(question.__doc__), df, Markdown(hint)) + +if __name__ == '__main__': + get_question(sys.modules[__name__], 'Question1') + \ No newline at end of file diff --git a/Week07/.population_practice.py b/Week07/.population_practice.py new file mode 100644 index 0000000..b1afa8f --- /dev/null +++ b/Week07/.population_practice.py @@ -0,0 +1,128 @@ +""" +CIS-54 Course SQL Questions +""" + +import sys +import inspect + +from IPython.display import HTML, Markdown, display +import sqlite3 +import pandas as pd + +conn = sqlite3.connect('../Databases/population.sqlite3') + +class Question01: + """ +## Population Data + +Write a query that select all rows from the `population` table. + +""" + answer = "select * from population limit 5;" + +class Question02: + """ +## Exploring the Population + +Write a query that shows how many 20-year-olds lived in Santa Cruz county in 1996. + +""" + answer = "select * from population where county = 'SANTA CRUZ' and age = 20 and year = 1996;" + +class Question03: + """ +## Total Population in a Year + +Write a query that shows the **total** population (all ages) of Santa Cruz county in 1996. +""" + answer = "select county, sum(pop_total) as total from population where county = 'SANTA CRUZ' and year = 1996" + +class Question04: + """ +## Total Population by Year + +Write a query that shows the **total** population of Santa Cruz county from 1996 to 2000. +""" + answer = """select county, year, sum(pop_total) as total from population where county = 'SANTA CRUZ' and year >= 1996 and year <= 2000 group by year;""" + +class Question05: + """ +## Demographics: Women and Men + +Write a query that shows what counties have more women than men in 2018. +""" + answer = """select county, sum(pop_male) as men, sum(pop_female) as women from population where year = 2018 group by county having women > men limit 5;""" + +class Question06: + """ +## Demographics: Ratio of Men and Women + +Write a query that shows the ratio of men and women (`pop_male` divided by `pop_female`) over the age of 18 by county in 2018. Order the results from the most female to the most male counties. + +*Problems with your ratio? Look at the first answer here: https://stackoverflow.com/questions/8305613/converting-int-to-real-in-sqlite* +""" + answer = """select county, 1.0 * sum(pop_male) / sum(pop_female) as ratio from population where year = 2018 and age >= 18 group by county order by ratio limit 5;""" + +class Question07: + """ +## California Demographics + +Write a query that combines the data on each county to show the population of California by age in 2018. +""" + answer = """select age, sum(pop_total) from population where year = 2018 group by age limit 5""" + +class Question08: + r""" +## Average Age + +Write a query that shows the average age of a person in California in 2018. + +*The formula for the average age is shown below.* + +\begin{equation*} +{Average} = \frac{\sum{ \left(Age + 0.5\right) * People}} {\sum{People}} +\end{equation*} +""" + answer = """select 1.0 * sum((0.5 + age) * pop_total) / sum(pop_total) as average from population where year = 2018;""" + +class Question09: + """ +## Oldest Counties + +Write a query that shows the average age of a person in each county in 2018. Order the query from oldest to youngest counties. +""" + answer = """select county, 1.0 * sum((0.5 + age) * pop_total) / sum(pop_total) as average from population where year = 2018 group by county order by average desc limit 5; """ + +class Question10: + """ +## Big Counties + +Write a query showing counties with a total population greater than one million people in 2018. +""" + answer = """select county, sum(pop_total) as total from population where year = 2018 group by county having total > 1000000;""" + + +########################################### +q_num = 0 + +def get_question(module, name=None): + global q_num + if name is None: + questions = [] + for name, member in inspect.getmembers(module): + if inspect.isclass(member) and name.startswith('Question'): + questions.append(member) + question = questions[q_num] + q_num += 1 + + else: + question = getattr(module, name) + + hint = '*This preview is limited to five rows.*' + df = pd.read_sql_query(question.answer, conn) + + return display(Markdown(question.__doc__), df, Markdown(hint)) + +if __name__ == '__main__': + get_question(sys.modules[__name__], 'Question1') + \ No newline at end of file diff --git a/Week07/__pycache__/.airports_practice.cpython-36.pyc b/Week07/__pycache__/.airports_practice.cpython-36.pyc new file mode 100644 index 0000000..8e50924 Binary files /dev/null and b/Week07/__pycache__/.airports_practice.cpython-36.pyc differ diff --git a/Week07/__pycache__/.population_practice.cpython-36.pyc b/Week07/__pycache__/.population_practice.cpython-36.pyc new file mode 100644 index 0000000..4cf5680 Binary files /dev/null and b/Week07/__pycache__/.population_practice.cpython-36.pyc differ diff --git a/Week07/__pycache__/.week07_practice.cpython-36.pyc b/Week07/__pycache__/.week07_practice.cpython-36.pyc new file mode 100644 index 0000000..f339f4f Binary files /dev/null and b/Week07/__pycache__/.week07_practice.cpython-36.pyc differ diff --git a/Week07/airports_practice.ipynb b/Week07/airports_practice.ipynb new file mode 100644 index 0000000..4a2fb20 --- /dev/null +++ b/Week07/airports_practice.ipynb @@ -0,0 +1,229 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext sql\n", + "%config SqlMagic.autolimit=100\n", + "%sql sqlite:///../Databases/flights.sqlite3\n", + "\n", + "from course import problem_set\n", + "problem_set.load_file('.airports_practice.py')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Week07/population_practice.ipynb b/Week07/population_practice.ipynb new file mode 100644 index 0000000..b5650a2 --- /dev/null +++ b/Week07/population_practice.ipynb @@ -0,0 +1,229 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext sql\n", + "%config SqlMagic.autolimit=100\n", + "%sql sqlite:///../Databases/population.sqlite3\n", + "\n", + "from course import problem_set\n", + "problem_set.load_file('.population_practice.py')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Week09/queen_anne_project.ipynb b/Week09/queen_anne_project.ipynb new file mode 100644 index 0000000..f481953 --- /dev/null +++ b/Week09/queen_anne_project.ipynb @@ -0,0 +1,411 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Queen Anne Project\n", + "\n", + "In this lab you will learn to use the SQL CREATE, INSERT, UPDATE and DELETE statements. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext sql\n", + "%config SqlMagic.autolimit=100\n", + "%sql sqlite://" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create the Customer Table\n", + "\n", + "In the cell below write an SQL create statement to create Queen Anne's customer table. The table is defined the following way:\n", + "\n", + "| Name | Type | Notes | \n", + "| --- | --- | --- | \n", + "| CustomerID | int | Primary Key |\n", + "| LastName | varchar(25) | |\n", + "| FirstName | varchar(25) | |\n", + "| Address | varchar(35) | |\n", + "| City | varchar(35) | |\n", + "| State | varchar(2) | |\n", + "| ZIP | varchar(10) | |\n", + "| Phone | varchar(12) | |\n", + "| Email | varchar(100) | |\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Insert Data Into the Customer Table\n", + "\n", + "In the cell below insert the following customer data:\n", + "\n", + "| ID | Lastname | FirstName | Address | City | State | ZIP | Phone | Email |\n", + "| --- | --- | --- | --- | --- |--- | --- | --- | --- |\n", + "| 1 | Shire | Robert | 6225 Evanston Ave N | Seattle | WA | 98103 | 206-524-2433 | Robert.Shire@somewhere.com |\n", + "| 2 | Goodyear | Katherine | 7335 11th Ave NE | Seattle | WA | 98105 | 206-524-3544 | Katherine.Goodyear@somewhere.com |\n", + "| 3 | Bancroft | Chris | 12605 NE 6th Street | Bellevue | WA | 98005 | 425-635-9788 | Chris.Bancroft@somewhere.com |\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create The Employee Table\n", + "\n", + "In the cell below use an SQL create statement to make the employee table:\n", + "\n", + "| Name | Type | Notes | \n", + "| --- | --- | --- | \n", + "| EmployeeID | int | Primary Key |\n", + "| LastName | varchar(25) | |\n", + "| FirstName | varchar(25) | |\n", + "| Phone | varchar(12) | |\n", + "| Email | varchar(100) | |\n", + "\n", + "Another" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Insert Employee Data \n", + "\n", + "In the cell below insert the following data into the employee table: \n", + "\n", + "| ID | LastName | FirstName | Phone | Email |\n", + "| --- | --- | --- | --- | --- | \n", + "| 1 | Stuart | Anne | 206-527-0010 | Anne.Stuart@QACS.com |\n", + "| 2 | Stuart | George | 206-527-0011 | George.Stuart@QACS.com |\n", + "| 3 | Matera | Mike | 831-555-1212 | Mike.Matera@QACS.com | \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create the Vendor Table\n", + "\n", + "In the cell below use an SQL create statement to make the vendor table:\n", + "\n", + "| Name | Type | Notes | \n", + "| --- | --- | --- | \n", + "| VendorID | int\t | Primary Key |\n", + "| CompanyName | varchar(100) | |\n", + "| ContactLastName | varchar(25) | NOT NULL |\n", + "| ContactFirstName | varchar(25) | NOT NULL |\n", + "| Address | varchar(35) | |\n", + "| City | varchar(35) | |\n", + "| State | varchar(2) | |\n", + "| ZIP | varchar(10) | |\n", + "| Phone | varchar(12) | NOT NULL |\n", + "| Fax | varchar(12) | |\n", + "| Email | varchar(100) | |\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Insert Vendor Data \n", + "\n", + "In the cell below insert the following data into the vendor table:\n", + "\n", + "| ID | CompanyName | ContactLastName | ContactFirstName | Address | City | State | ZIP | Phone | Fax | Email | \n", + "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |\n", + "| 1 | Linens and Things | Huntington | Anne | 1515 NW Market Street | Seattle | WA | 98107 | 206-325-6755 | 206-329-9675 | LAT@business.com | \n", + "| 2 | European Specialties | Tadema | Ken | 6123 15th Avenue NW | Seattle | WA | 98107 | 206-325-7866 | 206-329-9786 | ES@business.com | \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create the Item Table \n", + "\n", + "In the cell below use an SQL create staement to make the item table: \n", + "\n", + "| Name | Type | Notes | \n", + "| --- | --- | --- | \n", + "| ItemID | int\t | Primary Key |\n", + "| ItemDescription | varchar(255) | NOT NULL |\n", + "| PurchaseDate | datetime\t | NOT NULL |\n", + "| ItemCost | double | NOT NULL |\n", + "| ItemPrice | double | NOT NULL |\n", + "| VendorID | int\t | NOT NULL |\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Insert Item Data\n", + "\n", + "Insert the following data into the item table:\n", + "\n", + "| ID | ItemDescription | PurchaseDate | ItemCost | ItemPrice | VendorID |\n", + "| --- | --- | --- | --- | --- | --- | \n", + "| 1 | Antique Desk | 2013-11-07 | 1800.00 | 3000.00 | 2 |\n", + "| 2 | Antique Desk Chair | 2013-11-10 | 300.00 | 500.00 | 2 |\n", + "| 3 | Dining Table Linens | 2013-11-14 | 600.00 | 1000.00 | 1 |\n", + "| 4 | Candles | 2013-11-14 | 30.00 | 50.00 | 1 |\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create the Sale Table \n", + "\n", + "In the cell below use and SQL create statement to make the sale table:\n", + "\n", + "| Name | Type | Notes | \n", + "| --- | --- | --- | \n", + "| SaleID | int\t | Primary Key |\n", + "| CustomerID | int\t | FK - References the Customer Table |\n", + "| EmployeeID | int\t | FK - References the Employee Table |\n", + "| SaleDate | datetime | NOT NULL |\n", + "| SubTotal | double | |\n", + "| Tax | double | |\n", + "| Total | double | |\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Insert Sale Data \n", + "\n", + "Insert the following values into the sale table: \n", + "\n", + "| CustomerID | EmployeeID | SaleDate | SubTotal | Tax | Total |\n", + "| --- | --- | --- | --- | --- | --- |\n", + "| 1 | 1 | 2013-12-14 | 3500.00 | 290.50 | 3790.50 |\n", + "| 2 | 1 | 2013-12-15 | 1000.00 | 83.00 | 1083.00 |" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create the SaleItem Table\n", + "\n", + "In the cell below use an SQL create statement to make the SaleItem table:\n", + "\n", + "| Name | Type | Notes | \n", + "| --- | --- | --- | \n", + "| SaleID | int | Primary Key, FK - References the Sale Table|\n", + "| ItemID | int | Primary Key, FK - References the Item Table |\n", + "| ItemPrice | double | |\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Insert Sale Items \n", + "\n", + "Complete the sale cells by inserting the following data: \n", + "\n", + "| SaleID | ItemID | ItemPrice | \n", + "| --- | --- | --- | \n", + "| 1 | 1 | 3000.00 |\n", + "| 1 | 2 | 500.00 | \n", + "| 2 | 3 | 1000.00 | \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Changes to the Database\n", + "\n", + "Implement the following changes using the SQL UPDATE or DELETE commands:\n", + "\n", + " 1. Mike Matera gets fired! Remove him from the employee table\n", + " 2. The contact information for \"Linens and Things\" changed. The new contact is \"Bob Smith\"\n", + " 3. Price increases! Make the ItemPrice of everything double the ItemCost" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Query the Data\n", + "\n", + "Write selects for each of your tables. Do they contain what you expect?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Week10/.queen_anne_joins.py b/Week10/.queen_anne_joins.py new file mode 100644 index 0000000..50ad42a --- /dev/null +++ b/Week10/.queen_anne_joins.py @@ -0,0 +1,173 @@ +""" +CIS-54 Course SQL Questions +""" + +import sys +import inspect + +from IPython.display import HTML, Markdown, display +import sqlite3 +import pandas as pd + +conn = sqlite3.connect('../Databases/queen_anne.sqlite3') + +class Question01: + """ +## 1. Vendors and Items + +Join the table ITEM and VENDOR so that all items are listed with the following columns: + + - Description + - Item Cost + - Vendor Company Name + +""" + answer = "select item.itemdescription, item.itemcost, vendor.companyname from item, vendor where item.vendorid = vendor.vendorid limit 5" + +class Question02: + """ +## 2. Corporate Vendor Items + +Update the last query to only include vendors that have a non-NULL company name. +""" + answer = "select item.itemdescription, item.itemcost, vendor.companyname from item, vendor where item.vendorid = vendor.vendorid and vendor.companyname is not NULL limit 5" + +class Question03: + """ +## 3. Employee Sales + +Write a query that lists all sales with the name of the salesperson that made them. +""" + answer = "select * from sale, employee where sale.employeeid = employee.employeeid limit 5" + +class Question04: + """ +## 4. Sales Goals + +Update the last query to show the total sales by each employee. +""" + answer = "select FirstName, LastName, sum(Total) as Total from sale, employee where sale.employeeid = employee.employeeid group by FirstName, LastName limit 5" + +class Question05: + """ +## 5. Customer Sales + +Write a query that shows the names of the top customers in terms of sales. +""" + answer = """ +select FirstName, LastName, sum(Total) as Total +from customer, sale +where customer.customerid = sale.customerid +group by FirstName, LastName +order by total desc +limit 5; +""" + +class Question06: + """ +## 6. Unsold Items + +Write a query that shows all **unsold** items. +""" + answer = """select * from item where itemid not in (select itemid from sale_item) limit 5;""" + +class Question07: + """ +## 7. Customer Vendors + +Write a query that lists the customers who are also vendors. +""" + answer = """ +select firstname, lastname from customer +intersect +select contactfirstname, contactlastname from vendor +limit 5; +""" + +class Question08: + """ +## 8. Email List + +Write a query that lists all the names and email addresses in the database. +""" + answer = """ +select firstname, lastname, email from employee +union +select contactfirstname, contactlastname, email from vendor +union +select firstname, lastname, email from customer +limit 5; +""" + +class Question09: + """ +## 9. The Whole Enchilada + +Write a join that joins all the tables in the schema and produces and output table of every sale with: + + - The full name of the salesperson + - The full name of the customer + - The company name of the vendor + - The full contact name of the vendor + - The cost of the item + - The item's sale price +""" + answer = """ +select employee.firstname, employee.lastname, customer.firstname, customer.lastname, + vendor.companyname, vendor.contactlastname, vendor.contactfirstname, + item.itemcost, item.itemprice +from employee, customer, vendor, item, sale, sale_item +where sale.employeeid = employee.employeeid + and sale.customerid = customer.customerid + and sale.saleid = sale_item.saleid + and sale_item.itemid = item.itemid + limit 5 +; +""" + +class Question10: + """ +## 10. Sales by Employee and Customer + +Write a query that shows salesdata by salesperson and customer. Show the following: + + - The first and last name of the salesperson + - The customer's first and last name + - The total sales from that salesperson to that customer + +""" + answer = """ +select employee.firstname, employee.lastname, customer.firstname, customer.lastname, sum(Total) as Total +from employee, customer, sale +where employee.employeeid = sale.employeeid + and customer.customerid = sale.customerid +group by employee.employeeid, customer.customerid +limit 5 +; +""" + + +########################################### +q_num = 0 + +def get_question(module, name=None): + global q_num + if name is None: + questions = [] + for name, member in inspect.getmembers(module): + if inspect.isclass(member) and name.startswith('Question'): + questions.append(member) + question = questions[q_num] + q_num += 1 + + else: + question = getattr(module, name) + + hint = '*This preview is limited to five rows.*' + df = pd.read_sql_query(question.answer, conn) + + return display(Markdown(question.__doc__), df, Markdown(hint)) + +if __name__ == '__main__': + get_question(sys.modules[__name__], 'Question1') + \ No newline at end of file diff --git a/Week10/__pycache__/.queen_anne_joins.cpython-36.pyc b/Week10/__pycache__/.queen_anne_joins.cpython-36.pyc new file mode 100644 index 0000000..b9861ec Binary files /dev/null and b/Week10/__pycache__/.queen_anne_joins.cpython-36.pyc differ diff --git a/Week10/queen_anne_joins.ipynb b/Week10/queen_anne_joins.ipynb new file mode 100644 index 0000000..c4c4c9b --- /dev/null +++ b/Week10/queen_anne_joins.ipynb @@ -0,0 +1,238 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Queen Anne Joins\n", + "\n", + "This assignment will give you practice with joins in SQL" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext sql\n", + "%config SqlMagic.autolimit=100\n", + "%sql sqlite:///../Databases/queen_anne.sqlite3\n", + "\n", + "from course import problem_set\n", + "problem_set.load_file('.queen_anne_joins.py')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Week11/.pets_joins.py b/Week11/.pets_joins.py new file mode 100644 index 0000000..1ff60e7 --- /dev/null +++ b/Week11/.pets_joins.py @@ -0,0 +1,109 @@ +""" +CIS-54 Course SQL Questions +""" + +import sys +import inspect + +from IPython.display import HTML, Markdown, display +import sqlite3 +import pandas as pd + +conn = sqlite3.connect('../Databases/pets.sqlite3') + +class Question01: + """ +## 1. Pets and Breed + +Write a join query that joins PET_3 and BREED to output a table with the following attributes: + + - PET_3.PetName + - PET_3.PetBreed + - PET_3.PetDOB + - PET_3.PetWeight + - BREED.MinWeight + - BREED.MaxWeight + - BREED.AverageLifeExpectancy +""" + answer = """ +select + pet_3.PetName, pet_3.petbreed, pet_3.petdob, pet_3.petweight, + breed.minweight, breed.maxweight, breed.averagelifeexpectancy +from pet_3 join breed +on pet_3.petbreed = breed.breedname +limit 5; +""" + +class Question02: + """ +## 2. Unknown Breeds + +Update the last query to include the pets with an unknown breed. +""" + answer = """ +select + pet_3.PetName, pet_3.petbreed, pet_3.petdob, pet_3.petweight, + breed.minweight, breed.maxweight, breed.averagelifeexpectancy +from pet_3 left join breed +on pet_3.petbreed = breed.breedname +limit 5; +""" + +class Question03: + """ +## 3. Average Breed Weight + +Update query #1 to include a calculated column that is the average weight of the breed as defined by (MinWeight + MaxWeight) / 2. +""" + answer = """ +select + pet_3.PetName, pet_3.petbreed, pet_3.petdob, pet_3.petweight, + breed.minweight, breed.maxweight, breed.averagelifeexpectancy, + (breed.minweight + breed.maxweight) / 2 as `Average Weight` +from pet_3 join breed +on pet_3.petbreed = breed.breedname +limit 5; +""" + +class Question04: + """ +## 4. Fatties + +Filter query #3 to show only pets that are above average weight. +""" + answer = """ +select + pet_3.PetName, pet_3.petbreed, pet_3.petdob, pet_3.petweight, + breed.minweight, breed.maxweight, breed.averagelifeexpectancy, + (breed.minweight + breed.maxweight) / 2 as `Average Weight` +from pet_3 join breed +on pet_3.petbreed = breed.breedname +where pet_3.petweight > `Average Weight` +limit 5; +""" + + +########################################### +q_num = 0 + +def get_question(module, name=None): + global q_num + if name is None: + questions = [] + for name, member in inspect.getmembers(module): + if inspect.isclass(member) and name.startswith('Question'): + questions.append(member) + question = questions[q_num] + q_num += 1 + + else: + question = getattr(module, name) + + hint = '*This preview is limited to five rows.*' + df = pd.read_sql_query(question.answer, conn) + + return display(Markdown(question.__doc__), df, Markdown(hint)) + +if __name__ == '__main__': + get_question(sys.modules[__name__], 'Question1') + \ No newline at end of file diff --git a/Week11/pets_joins.ipynb b/Week11/pets_joins.ipynb new file mode 100644 index 0000000..4a7e9ba --- /dev/null +++ b/Week11/pets_joins.ipynb @@ -0,0 +1,131 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Pets Joins\n", + "\n", + "This assignment will give you practice with outer joins in SQL" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext sql\n", + "%config SqlMagic.autolimit=100\n", + "%sql sqlite:///../Databases/pets.sqlite3\n", + "\n", + "from course import problem_set\n", + "problem_set.load_file('.pets_joins.py')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem_set.get_question()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/images/mysql_killgrave_screen.png b/images/mysql_killgrave_screen.png new file mode 100644 index 0000000..7ab0722 Binary files /dev/null and b/images/mysql_killgrave_screen.png differ diff --git a/images/mysql_workbench_new_connection.png b/images/mysql_workbench_new_connection.png new file mode 100644 index 0000000..5dbee5d Binary files /dev/null and b/images/mysql_workbench_new_connection.png differ diff --git a/images/mysql_workbench_open_screen.png b/images/mysql_workbench_open_screen.png new file mode 100644 index 0000000..be1e974 Binary files /dev/null and b/images/mysql_workbench_open_screen.png differ diff --git a/labs/actors_fds.md b/labs/actors_fds.md new file mode 100644 index 0000000..c255a4c --- /dev/null +++ b/labs/actors_fds.md @@ -0,0 +1,68 @@ +# Lab: Actors and Movie Functional Dependencies + +This lab takes you through the process of creating an *intersection table* to handle a Multivalued Dependency. + +> You must have completed last week's lab [Referential Integrity](referential_integrity.md). + +## Step 1: Add Movies + +Create a table to store movies. The table should have the following definition: + +movie ( title, year ) + +Add the following information to your movie table (it's the movies from the Oscar table: + + 1. The Godfather: Part II, 1975 + 2. Kramer vs. Kramer: 1980 + 3. Raging Bull: 1981 + 4. Sophie's Choice: 1983 + 5. The Iron Lady: 2012 + 6. Darkest Hour: 2018 + +Now add another actor to your table: + + 1. Al Pacino, April 25 1940, New York, NY + +## Step 2: Create an Intersection Table Between Actor and Move + +Intersection tables sometimes have funny names like `actor_has_movie` because they form a bridge between two tables when there's an MVD. In this case we have a better name for our intersection table. We will call it `starring` and the definition should look like this: + +starring ( ActorID, Movie) + +> Notice! Both attributes are primary keys **and** foreign keys. + +Intersection tables will always have at least two foreign keys becasue they join two tables together. + +## Step 3: Populate the Intersection Table + +Populate the intersection table with the movies that actors have appeared in: + + 1. Meryl Streep - Kramer vs. Kramer and The Iron Lady + 2. Robert DeNiro - The Godfather: Part II and Raging Bull + 3. Gary Oldman - The Darkest Hour + 4. Al Pacino - The Godfather: Part II + +## Step 4: Replace Columns in the Oscar Table + +The oscar table now refers to data that's in the `movie` table. Place a foreign key constraint in the `oscar` table that ensures an oscar is given to a movie that's in the `movie` table. + +## Step 5: Run Some Queries + +You now have an intersection table that satisfies the MVDs: + + ActorName -> MovieTitle + MovieTitle -> ActorName + +You can query actors and movies with the following SQL. + +```sql +select * + from actor, starring, movie + where + actor.id = starring.ActorID + AND starring.Movie = movie.title; +``` + +## Turn In + + 1. Export your schema to a file called `actors_fds.sql`. diff --git a/labs/connect_to_killgrave.md b/labs/connect_to_killgrave.md new file mode 100644 index 0000000..0628d6f --- /dev/null +++ b/labs/connect_to_killgrave.md @@ -0,0 +1,40 @@ +# Connect to Killgrave + +Killgrave is a MySQL server in Amazon's cloud. The class will use Killgrave as a shared DBMS, which will allow me to share schemas with you. This lab will take you through establishing a connection to Killgrave. + +## Step 1: Start MySQL Workbench + +On the opening screen of MySQL workbench click the plus (`+`) icon. + +![](../images/mysql_workbench_open_screen.png) + +## Step 2: Enter Connection Information + +You will see the new connection dialog shown below: + +![](../images/mysql_workbench_new_connection.png) + +Enter the following information: + + * **Connection Name**: Killgrave + * **Hostname**: `killgrave.ca3hsvz6gvc4.us-west-2.rds.amazonaws.com` + * **Username**: Your Cloud9 Username + * **Password**: Your Cloud9 Password + +> Note: You will be prompted to enter your password later. + +Click "OK" to create the new connection. + +## Step 3: Open the Connection + +When you return to the home screen you should see a new connection. Click it and you'll be prompted for your password. You can ask MySQL workbench to store you password for future connection attempts. + +Once connected you will see a screen similar to this: + +![](../images/mysql_killgrave_screen.png) + +**Take a screenshot of the connection screen** + +## Turn In + +Turn in the screenshot from step 3. diff --git a/labs/install_mysql_server.md b/labs/install_mysql_server.md new file mode 100644 index 0000000..7766ca3 --- /dev/null +++ b/labs/install_mysql_server.md @@ -0,0 +1,13 @@ +# Install MySQL Server + +When you're handling a large dataset it can be painfully slow to import CSV files. Network latency is the main slowdown when you import into Killgrave. In this lab you will follow directions to install MySQL server on your laptop or home machine. + +> MySQL Server is already installed on Cabrillo machines + +## The Official Instructions + +Follow the instructions on MySQL's site: + +> [https://dev.mysql.com/doc/refman/8.0/en/installing.html](https://dev.mysql.com/doc/refman/8.0/en/installing.html) + +This lab is optional, but recommended if you are using your own computer. There's nothing to turn in. diff --git a/labs/mysql_first_schema.md b/labs/mysql_first_schema.md new file mode 100644 index 0000000..c908349 --- /dev/null +++ b/labs/mysql_first_schema.md @@ -0,0 +1,98 @@ +# Your First Schema + +In this lab you will create a schema and some tables two different ways. MySQL Workbench allows you to do many things with little or no knowledge of SQL. That's very helpful for beginners but, as this class progresses I hope that, like me, you'll learn to crave the power of SQL and not depend on the GUI. In this lab we'll create a schema with two tables and add some data to it. + +## Chapter Questions + +Answer the following questions: + + 1. What is a modification problem. Name two types of modification problem. + 2. What does SQL stand for? + 3. Define the term metadata and give some examples of metadata. + +## Using the GUI + +In this part you will create a new schema. Your new schema name must begin with your login ID. For example: + +> matmic54_firstschema + +Use the Create Schema button shown below: + +![](https://sites.google.com/a/lifealgorithmic.com/cabrillo-home/_/rsrc/1513330349177/home/cis-154/lab-2---your-first-schema/Create%20Schema.png?height=240&width=400) + +That will bring up the create schema tab. Name your schema and apply as shown: + +![](https://sites.google.com/a/lifealgorithmic.com/cabrillo-home/_/rsrc/1454526758030/home/cis-154/lab-2---your-first-schema/Name%20and%20Apply.png?height=240&width=400) + +MySQL Workbench will show you what SQL is about to execute and ask you to confirm: + +![](https://sites.google.com/a/lifealgorithmic.com/cabrillo-home/_/rsrc/1513330349177/home/cis-154/lab-2---your-first-schema/Create%20Schema%20Apply.png?height=387&width=400) + +Click Apply. Now you should see your schema on the left hand side of your window: + +![](https://sites.google.com/a/lifealgorithmic.com/cabrillo-home/_/rsrc/1454526758030/home/cis-154/lab-2---your-first-schema/Schema%20Created.png?height=240&width=400) + +Double click the name of your schema to select it as the active one. Then select the "New Table" button. This will bring up the new table tab. Your new table should have the following properties: + + * Name: actor + * Columns: + * id (type INT, PK, NN) + * name (type VARCHAR(45), NN) + * birthday (type DATE, NN) + * hometown (type VARCHAR(45), NN) + +You table should look like this: + +![](https://sites.google.com/a/lifealgorithmic.com/cabrillo-home/_/rsrc/1454526758030/home/cis-154/lab-2---your-first-schema/New%20Table.png?height=240&width=400) + +Select apply to create your table and you will see the SQL command that creates your table: + +![](https://sites.google.com/a/lifealgorithmic.com/cabrillo-home/_/rsrc/1454526758030/home/cis-154/lab-2---your-first-schema/Apply%20Table.png?height=387&width=400) + +Click "Apply". Next you will add values to the table. Pull open the lab2 schema. When you hover over the actor table you will see a set of icons. The right-most icon looks like a table. Select it and it will bring up the table editor as shown below: + +![](https://sites.google.com/a/lifealgorithmic.com/cabrillo-home/_/rsrc/1513330349177/home/cis-154/lab-2---your-first-schema/Add%20Actor%20Data.png?height=240&width=400) + +Add the following people to the actor table as shown in the picture above: + +| ID | Name | Birthday | Hometown | +| --- | --- | --- | --- | +| 1 | Robert De Niro | 1943-08-17 | New York, NY | +| 2 | Meryl Streep | 1949-06-22 | Summit, NJ | + +When you're done click Apply and the SQL statements will be shown to you. Select Apply again. You have now populated the actors table. + +## Creating Tables Using SQL + +Now you will create tables using SQL. Select the "Query 1" tab in MySQL Workbench. This tab allows you to enter SQL statements. You can load and save SQL files as well as run them step-by-step. In the tab enter the following SQL statements: + +```sql +CREATE TABLE oscar (year INT NOT NULL, category VARCHAR(45) NOT NULL, movie VARCHAR(45), actor INT NOT NULL); + +INSERT INTO oscar VALUES (1981, 'Best Actor', 'Raging Bull', 1); +INSERT INTO oscar VALUES (1975, 'Best Suporting Actor', 'The Godfather: Part II', 1); +INSERT INTO oscar VALUES (2012, 'Best Actress', 'The Iron Lady', 2); +INSERT INTO oscar VALUES (1983, 'Best Actress', 'Sophie\'s Choice', 2); +INSERT INTO oscar VALUES (1980, 'Best Supporting Actress', 'Kramer vs. Kramer', 2); +``` + +With the above SQL statements in the editor press the button with the lightning icon to execute them all. It's much faster to create and edit tables when you know SQL. Verify that your table contains the data. It must be turned in with your assignment. + +## Export your Schema + +MySQL workbench can export your schema so you can load it into another DBMS. To export a schema select the server menu item at the top of the window: + + Server -> Data Export + +That will bring up the export dialog as shown: + +![](https://sites.google.com/a/lifealgorithmic.com/cabrillo-home/_/rsrc/1513330349177/home/cis-154/lab-2---your-first-schema/Export%20Lab%202.png?height=240&width=400) + +Save your schema in a file called `first_schema_export.sql` and submit your file for credit. + +## Turn In + + * The answers to the chapter questions in a file called `chapter_questions`. The file can be any text format (e.g. Word or plain text) + * Your `first_schema_export.sql` file + +Submit your homework on canvas. diff --git a/labs/realdata_1_cabrillo_import.md b/labs/realdata_1_cabrillo_import.md new file mode 100644 index 0000000..b146af3 --- /dev/null +++ b/labs/realdata_1_cabrillo_import.md @@ -0,0 +1,145 @@ +# Using Real Data: Cabrillo Courses + +In this lab you will examine some of the issues and trade-offs when you begin to use real data in a schema. The data that we will use comes from the [State of California's Data Mart](https://datamart.cccco.edu/), which has many other interesting data sets. I've downloaded data for Cabrillo College from this page: + +[https://datamart.cccco.edu/Courses/College_MCF.aspx](https://datamart.cccco.edu/Courses/College_MCF.aspx) + +The data was downloaded in Microsoft Excel format, fixed up an exported to CSV format. + +## Step 1: Import the CSV Files + +Complete instructions on importing table data can be found here: + +[https://dev.mysql.com/doc/workbench/en/wb-admin-export-import-table.html](https://dev.mysql.com/doc/workbench/en/wb-admin-export-import-table.html) + +The dataset has three files: + + - [MasterCourseFile.csv](../../_static/cis-54/MasterCourseFile.csv) - The list of all Cabrillo courses. + - [ProgramFile.csv](../../_static/cis-54/ProgramFile.csv) - The list of Cabrillo programs. (A program is a degree or certificate.) + - [ProgramCourseFile.csv](../../_static/cis-54/ProgramCourseFile.csv) - The intersection table that maps courses into programs. + +The Excel files have been slightly modified to remove problems that will break the CSV import. I have deleted extra rows and columns that make the formatting nice but mess up imports. + +Create a schema in MySQL (use your local computer if you can because it's faster). In the tables element in the schema tree view on the left select the "Table Data Import Wizard". Follow the steps to import each CSV file. **Leave all settings at their defaults.** + +## Step 2: Import Course Data + +Public datasets often have problems that prevent imported CSV data from being used easily. Common problems include: + + - Undefined or unknown columns. (e.g. what does "Funding Category" mean?) + - Columns that have no useful data (e.g. "Total Units" is always 0) + - Multiple candidate keys (e.g. "Control Number" and "Course ID") + - Non-normalized data. The ProgramCourseFile.csv contains data from MasterCourseFile.csv and ProgramFile.csv. That makes the data easier to work with in Excel but is not great for SQL. + - Bad Data. In a spredsheet it's hard to find rows with confusing data or that have NULL keys. + +In this step we'll create tables to hold our data. Our new tables will have the column names and data types we want. + +```sql +create table course ( + ControlNumber char(12) primary key, + CourseID char(12), + TOPCode char(6), + CreditStatus char(1), + MaximumUnits float, + MinimumUnits float, + SAMCode char(1), + Date date +); +``` + + +Now let's insert the data: + +```sql +insert into course (ControlNumber, CourseID, TOPCode, + CreditStatus, MaximumUnits, MinimumUnits, + SAMCode, Date) + select `Control Number`, `Course ID`, `TOP Code`, + `Credit Status`, `Maximum Units`, `Minimum Units`, + `SAM Status`, `Issue/Update Date` + from MasterCourseFile; +``` + +## Step 3: Create the Program Table + +The course data imported easily, using exactly the key we'd hoped for. The program data is a bit more problematic. Let's inspect the source data to look for candidate keys. This query shows you if `Program Control Number` is a workable key: + +```sql +select `Program Control Number`, count(*) + from ProgramFile + group by `Program Control Number` + having count(*) > 1; +``` + +It's not! Let's drill down to see why: + +```sql +select * from ProgramFile + where `Program Control Number` = ''; +``` + +Notice that all of the results have "Draft", "Revision", "Deleted" or "Review" in the `Proposal Status` column. This might be the reason that they don't have a control number yet. We cannot simply ignore this data so our table needs a surrogate key. + +```sql +create table program ( + ID int primary key auto_increment, + ControlNumber char(5), + Title varchar(64), + TOPCode char(6), + AwardType char(1), + CreditType char(1), + ApprovedDate date, + Status varchar(16), + InactiveDate date +); +``` + +## Step 4: Import Program Data + +Now let's bring in the data from the `ProgramFile` table. This query inserts data, excluding the `ID` field which will automatically number itself because of the `auto_increment` satetement. + +```sql +insert into program (ControlNumber, Title, TOPCode, AwardType, CreditType, ApprovedDate, Status, InactiveDate) + select `Program Control Number`, `Title`, `TOP Code`, `Program Award`, + `Credit Type`, IF (`Approved Date` = '', NULL, `Approved Date`), + TRIM(`Proposal Status`), IF (`Inactive Date` = '', NULL, `Inactive Date`) + from ProgramFile; +``` + +Notice the select alters some of the data in the `ProgramFile` table using SQL functions. The insert would fail otherswise. Here's what's done: + +```sql +TRIM(`Proposal Status`) +``` + +The `Proposal Status` field has extraneous spaces at the end. The `TRIM` function removes whitespace from the beginning and the end of the data. + +```sql +IF (`Approved Date` = '', NULL, `Approved Date`) +``` + +This statement says, *If the row contains an empty Approved Date replace it with NULL otherwise use the Approved Date from the row.* This statement fixes the situation where NULL values in the spreadsheet are represented by an empty cell. + +> You can find all of the functions available to MySQL here: +> +> [https://dev.mysql.com/doc/refman/5.7/en/functions.html](https://dev.mysql.com/doc/refman/5.7/en/functions.html) + +## Step 5: Create the Intersection Table + +Finally, let's create the intersection table. Note, this table does not have foreign keys, attempting to set an FK constraint in this table will fail because there are problems with the data and becuasue `ControlNumber` is not a key in the foreign tables. We'll address those problems next week. + +```sql +create table program_course ( + ID int primary key auto_increment, + ProgramControlNumber char(5), + CourseControlNumber char(12) +); + +insert into program_course (ProgramControlNumber, CourseControlNumber) + select `Program Control Number`, `Course Control Number` + from ProgramCourseFile; +``` + +## Turn In + +Export your schema into a file called `cabrillo_datamart.sql` and submit it on Canvas. diff --git a/labs/realdata_2_cabrillo_keys.md b/labs/realdata_2_cabrillo_keys.md new file mode 100644 index 0000000..5da334e --- /dev/null +++ b/labs/realdata_2_cabrillo_keys.md @@ -0,0 +1,71 @@ +# Keys in Real Data: Cabrillo Courses + +In this lab we will examine some trade-offs when addressing problems with data. This lab builds on the schema that we imported in the [Using Real Data: Cabrillo Courses](realdata_1_cabrillo_import.md) lab. + +## Step 1: Keys in the Program Data + +This query shows the problem with the program data: + +```sql +select * from ProgramFile + where `Program Control Number` = ''; +``` + +Some records don't have a control number. What can we do about it? Let's delete the rows and re-create the program table with a key. + +```sql +create table program ( + ControlNumber char(5) primary key, + Title varchar(64), + TOPCode char(6), + AwardType char(1), + CreditType char(1), + ApprovedDate date, + Status varchar(16), + InactiveDate date +); + +# Truncates some dates that also have time of day. Ignore. +insert into program (ControlNumber, Title, TOPCode, AwardType, CreditType, ApprovedDate, Status, InactiveDate) + select `Program Control Number`, `Title`, `TOP Code`, `Program Award`, + `Credit Type`, IF (`Approved Date` = '', NULL, `Approved Date`), + TRIM(`Proposal Status`), IF (`Inactive Date` = '', NULL, `Inactive Date`) + from ProgramFile + where `Program Control Number` != ''; +``` + +Note the `where` clause in the insert/select statement removes rows with empty control numbers. + +## Step 2: Keys in the Intersection Table + +Now let's fix the `program_course` table to use our new key. This too will encounter problems with empty control numbers. Run this query to check for bad keys: + +```sql +select `Program Control Number`, `Course Control Number`, count(*) + from ProgramCourseFile + group by `Program Control Number`, `Course Control Number` + having count(*) > 1; +``` + +There are courses that map to empty programs. Again, we're going to discard this data because it's hard to figure out where these courses belong. + +```sql +create table program_course ( + ProgramControlNumber char(5), + CourseControlNumber char(12), + constraint primary key (ProgramControlNumber, CourseControlNumber), + constraint prog_course_fk_1 foreign key (ProgramControlNumber) + references program (ControlNumber), + constraint prog_course_fk_2 foreign key (CourseControlNumber) + references course (ControlNumber) +); + +insert into program_course (ProgramControlNumber, CourseControlNumber) + select `Program Control Number`, `Course Control Number` + from ProgramCourseFile + where `Program Control Number` != ''; +``` + +## Turn In + +Export your schema into a file called `cabrillo_datamart_keys.sql` and submit it on Canvas. diff --git a/labs/referential_integrity.md b/labs/referential_integrity.md new file mode 100644 index 0000000..5426d8d --- /dev/null +++ b/labs/referential_integrity.md @@ -0,0 +1,97 @@ +# Referential Integrity + +In this lab you'll use a *foreign key constraint* to have MySQL enforce rules in your database. A foreign key constraint causes MySQL (and other relational DBMSes) to guarantee that rows in one table match rows in another table. In your first schema you entered actors and Oscar wins. What happens if you enter an oscar for an actor that's not in your database? + +> You must have completed last week's lab [Your First Schema](mysql_first_schema.md). + +## Step 0: Update the Oscar Table + +In this lab you'll have to enter data into the Oscar table. In order to be able to edit a table in MySQL Workbench the table must have a primary key column (or columns). Copy this query into an editor window in MySQL Workbench and execute it by placing the cursor over the query and pressing the lightning bolt with cursor button. + +```sql +ALTER TABLE oscar ADD PRIMARY KEY (`year`, `category`); +``` + +> Note: Step 2 will only be possible after running this query. + +## Step 1: A Join Query + +A *join* is an SQL query that operates on more than one table. Copy this query into the SQL editor window: + +```sql +select name, category, movie from oscar, actor where oscar.actor = actor.id; +``` + +Execute the query by placing the cursor over the query and pressing the lightning bolt with cursor button in MySQL worbench. You should see this output: + +|name | category | movie | +| --- | --- | --- | +| Robert De Niro | Best Actor | Raging Bull | +| Robert De Niro | Best Suporting Actor | The Godfather: Part II | +| Meryl Streep | Best Actress | The Iron Lady | +| Meryl Streep | Best Actress | Sophie's Choice | +| Meryl Streep | Best Supporting Actress | Kramer vs. Kramer | + +## Step 2: Corrupt the Data + +What happens when you add an Oscar but don't have a record of the actor? Add the following information to your oscar table: + + * Year: 2018 + * Category: Best Actor + * Movie: Darkest Hour + * Actor: 3 + +> Be sure to apply your changes. + +Notice a problem? There is no actor #3 because we haven't entered Gary Oldman. Rerun the join query in Step 1 and you'll notice that even though you have a record of the 2018 Best Actor award it's not shown. + +> Delete the 2018 best actor row before moving ahead. + +## Step 4: Add a Constraint + +The DBMS should prevent the update we made in step 2 until there's a matching actor. In this step we'll create a foreign key constraint for the purpose. In class I did a walkthrough of this process. The summary is: + + 1. Edit the oscar table by clicking the wrench icon next to the table name. + 2. Select the "Foreign Keys" tab at the bottom of the editor pane. + 3. Select the "Foreigh Key Name" field in the list, a default name of "fk_oscar_1" will appear. Keep that name and press "Enter" while editing that field. + 4. In the "Referenced Table" field select your actor table. + 5. In the "Foreign Key Columns" pane check the box next to "actor". A value will appear in the "Referenced Column" field. + 6. Select "id" in the referenced column field. + 7. Click "Apply", then "Apply" again in the popup. + +> If you see this error: +> +> ERROR 1452: Cannot add or update a child row: a foreign key constraint fails +> +> You must delete the 2018 oscar row and repeat Step 4 from the start. + +Test your constraint by attempting to execute the following SQL: + +```sql +insert into oscar values ('2018', 'Best Actor', 'Darkest Hour', 3); +``` + +You will see an error in the bottom pane. The error is: + +``` +Error Code: 1452. Cannot add or update a child row: a foreign key constraint fails (`matera_MikesFirstSchema`.`oscar`, CONSTRAINT `fk_oscar_1` FOREIGN KEY (`actor`) REFERENCES `actor` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION) +``` + +An oscar winner must be in the actor table! + +## Step 5: Add Gary Oldman + +Add Gary Oldman's information: + + * ID: 3 + * Name: Gary Oldman + * Birthday: 1958-03-21 + * Hometown: London, England + +After Gary has been added re-run the insert query from the previous step and the join query from Step 1. They work! + +## Turn In + +Export your data into a file called `referential_integrity.sql` and submit the file on Canvas. + + diff --git a/pages/get_mysql_workbench.md b/pages/get_mysql_workbench.md new file mode 100644 index 0000000..81b7c88 --- /dev/null +++ b/pages/get_mysql_workbench.md @@ -0,0 +1,18 @@ +# Install MySQL Workbench + +This lab will get you setup with MySQL Workbench, a graphical tool used to access MySQL databases. MySQL Workbench works on Windows, Mac and Linux. + +> If you plan to use school computers you can skip this lab. + +## Download and Install + +MySQL workbench is available for free from the link below: + +> [https://www.mysql.com/products/workbench/](https://www.mysql.com/products/workbench/) + +Follow the instructions for your operating system. + +## Turn In + +* A screenshot of MySQL Workbench on your computer. + \ No newline at end of file diff --git a/pages/setup_cloud9.md b/pages/setup_cloud9.md new file mode 100644 index 0000000..456d6f9 --- /dev/null +++ b/pages/setup_cloud9.md @@ -0,0 +1,62 @@ +# Setup Cloud9 IDE + +This lab will take you through claiming your Cloud9 IDE account and installing the class' Jupyter Notebooks. + +## Login to AWS + +Make sure you know your username and password. You can figure out what they are by reading the Access FAQ: + +> [Computer Access FAQ](../faq.html) + +Sign in to AWS using this link: + +> [Cloud9 IDE](https://957903271915.signin.aws.amazon.com/console) + +## Install the Course Files + +The course content is delivered using [Jupyter](https://jupyter.org/) Notebooks. The Jupyter Notebook is an open-source web application that allows you to create and share documents that contain live code, equations, visualizations and narrative text. Uses include: data cleaning and transformation, numerical simulation, statistical modeling, data visualization, machine learning, and much more. + +### Step 1: Initialize my Installer +Copy and paste the following command in your Cloud9 terminal: + +```bash +cd ~ && wget -q -O - https://github.com/mike-matera/CourseNotebook/archive/master.tar.gz | tar -zxvf - --strip-components=1 +``` + +The output should look like this: + + + +### Step 2: Set the Course Location + +Now execute this command to set the location of course content: + +```bash +cd ~ && echo "https://s3-us-west-2.amazonaws.com/notebooks-course-content/cis-54/content.tar.gz" > .course +``` + +### Step 3: Run the Updater + +Finally run the `update` command to setup your Cloud9 environment and install the notebooks. + +```bash +update +``` + +The initial update will take a couple of minutes. After the update is complete you should see the course content in the left pane. + + + +> Note: The course content changes so this picture might not look exactly like your finished install. + +## Run the Notebook + +If you have done everything correctly you should be able to run the `notebook` command: + +```bash +notebook +``` + +The `notebook` command will have output that presents you a URL. Open the URL in Cloud9 by clicking on it and selecting "Open". See the picture below: + + diff --git a/projects/cis_classes_fds.md b/projects/cis_classes_fds.md new file mode 100644 index 0000000..f5be337 --- /dev/null +++ b/projects/cis_classes_fds.md @@ -0,0 +1,59 @@ +# Project: Functional Dependencies + +In the previous two projects you've gathered and refined the data on CIS courses taught this semester. In this one you will state the functional dependencies in your data and use them to validate your choice of keys. + +## Important Attributes + +In your previous projects you collected a bunch of attributes regarding courses, sections and instructors from the catalog and SALSA. You've made choices about what attributes are relevant in your schema. For this project you should have *at least* the attributes listed here. You are free to add as many others as you like: + + 1. Instructor Name + 2. Instructor Title + 3. Instructor Phone Number + 4. Course Number + 5. Course Title + 6. Course Units + 7. Section Times + 8. Section Room + 9. Section Instructor + 10. Section Course + +## Describing Tables + +As mentioned in class there's a way to describe a table in documentation. In this assignment you are required to use the format. As a reminder a table is described like this: + +TableName ( key1, key2, attr1, attr2, *fk1*, *fk2* ) + +For example, if you had a `Section` table that looked like this: + +| SectionNumber | Room | Time | Course | Instructor | +| --- | --- | --- | --- | --- | +| 1 | 828 | Th 5:30-9:30 | cis-54 | Mike Matera | + +Assuming your `Course` and `Instructor` columns are foreign keys your table definition looks like this: + +Section ( SectionNumber, Room Time, *Course*, *Title* ) + +## Finding Functional Dependencies + +Start by listing all of the attributes that you track in your schema. Once you have them listed write out the functional dependencies in the "arrow" form shown in class. If you use surrogate keys include them. Watch out for incorrect FDs that don't use a surrogate key. For example, this FD is correct: + + InstructorID -> ( InstructorName, InstructorPhone, InstructorTitle ) + +This FD is **incorrect** because your schema won't support two "John Smiths": + + InstructorName -> ( InstructorPhone, InstructorTitle ) + +List your FDs clearly and verify that every attributes is represented in an FD. **Watch out for multivalued dependencies** there are some in there! + +## Rebuild your Schema + +With FDs in hand describe your schema using the table syntax above. Also, update your schema in SQL. Once your updates are complete export your schema and submit the written part of the assignment. + +## Turn In + +Please turn in the following: + + 1. A document with your FDs and Tables called `cis_fds.*` (It can't be text because you need underlines and italics.) + 2. You exported database called `cis_fds.sql` + + \ No newline at end of file diff --git a/projects/cis_classes_keys_and_constraints.md b/projects/cis_classes_keys_and_constraints.md new file mode 100644 index 0000000..5b43627 --- /dev/null +++ b/projects/cis_classes_keys_and_constraints.md @@ -0,0 +1,65 @@ +# Project: Keys and Constraints + +In the [CIS Course Schema](cis_classes_schema.md) you gathered information about the CIS department and this semester's classes. In this project you will further the construction of your schema by ensuring it follows relational rules. Remember the eight relational rules are: + + 1. Each row holds information about one entity. + 2. Each column holds information about one attribute. + 3. Each cell holds a single value. + 4. All entries in a column have the same type. + 5. Each column has a unique name. + 6. The column order is unimportant. + 7. The row order is unimportant. + 8. Each row is unique. + +You may or may not have organized your data according to rules like #3. MySQL (and all SQL) forces you to obey rule #4, for example. + +> Do the [Referential Integrity Lab](../labs/referential_integrity.md) before you begin. + +## Split Courses and Sections + +Your first schema captured all of the spring catalog course data into one table. That was okay last week, but your courses table stores two entities, which will cause modification problems. The table stores information about a course (e.g. title and units) and it stores information about a section (e.g. section number, semester and times). Update your schema to separate courses and sections. + +Before you create your new tables consider the following questions? + + 1. What are the *attributes* of a course? + 2. What are the *attributes* of a section? + +Think about the attributes and write them down. Remember attributes should belong to the entity that they describe. Again, ask yourself which of the attributes above are *keys*. + +Your new schema should have three tables: + + 1. Course + 2. Section + 3. Instructor + +Use a foreign key constraint to ensure that all sections have a corresponding course. + +## Select your Keys + +MySQL forces you to have primary keys. The name is a bit misleading because you can have **multiple** columns as primary keys. These are knows as composite keys. For each of the tables think about the attribute or attributes you will use for a key. Separately you will turn in answers to the following questions: + + 1. What is the key of your Course table? What kind of key is it (e.g. a surrogate key, composite key or a single-value key) + 2. What is the key of your Section table? What kind of key it it? + 3. What is the key of your Instructor table? What kind of key is it? + +You should turn in the answers to these questions in a document called `keys_and_constraints`. + +## Add Constraints to Section and Instructor + +Additionally add a referential integrity constraint between Section and Instructor. The constraint should ensure that the instructor of a section is present in the instructor table. You may have to change your data to make this work. + +## Chapter Questions + +Answer the following questions and add them to your `keys_and_constraints` document. + + 1. Define the term *entity* and give and example of an entity. + 2. Define the term *unique key* and give an example. + 3. What is a *surrogate key* and why would you use one? + +## Turn In + +When you're finished in MySQL Workbench, export your database into a file called `keys_and_constraints.sql`. Submit the following on Canvas: + + * `keys_and_constraints.sql` - The SQL export + * `keys_and_constraints.xxx` - A document with answers to the questions (it can be any kind of document). + \ No newline at end of file diff --git a/projects/cis_classes_schema.md b/projects/cis_classes_schema.md new file mode 100644 index 0000000..f32c575 --- /dev/null +++ b/projects/cis_classes_schema.md @@ -0,0 +1,64 @@ +# Project: CIS Course Schema + +This project will help you become familiar with structuring data into tables and lists. The goal of the project is to get you thinking about the data and metadata that's necessary to organize information. + +## The Data + +You will use the data from the Cabrillo Spring 19 course schedule: + +> [Cabrillo's Spring Schedule](https://www.cabrillo.edu/publications/schedule/spring/fullprintversion.pdf) + +Your database should contain all of the classes in the CIS department. You don't have to enter classes from other departments. You will also need to get information about all of the CIS instructors from Cabrillo's SALSA directory: + +> [Cabrillo's SALSA Directory](https://www.cabrillo.edu/salsa/peoplefinder.php?searchType=program&searchValue=18) + +## Creating your Schema + +*You should have already completed the [Your First Schema](../labs/mysql_first_schema.md) lab. The lab shows you how to create tables in MySQL. I also did a walkthrough in class.* + +### Start with Metadata + +You should capture as much information as possible from the the schedule and SALSA. What items of data do you want to capture? How will you name those data items? Some answers are easier than others and you have the flexibility to decide for yourself. For example you could represent in a table like this: + +| Department | Course Number | Section | Title | +| --- | --- | --- | --- | +| CIS | 54 | 1 | Introduction to Databases | + +Or you could do this: + +| Course | Section | Title | +| --- | --- | --- | +| CIS-54 | 1 | Introduction to Databases | + +Using your metadata as columns, create two tables in MySQL. One for courses and one for instructors. + +### Choose a Key + +Your tables must have a key. Choose one of the columns in your schema to be the key for the table. In MySQL Workbench you will select the "PK" checkbox for your key. + +> IMPORTANT: Two rows cannot have the same primary key. Choose your key carefully! + +### Enter the Data + +With your tables created go through all the courses and enter the data. Double check your information to be sure the data is complete. The purpose of this project is not data entry but having all the data is essential. + +### Export Your Schema + +Export your schema into an SQL file called `cis_courses.sql`. You will submit the file with this week's assignments. + +## Schema Questions + +Answer the following questions about your schema: + + 1. What are the related columns between your two tables? + 2. What are the keys in your data? + 3. Name one modification problem your schema might have and why. + +Answer the questions in a file named `cis_courses_answers`. The file can be any document format. + +## Turn In + + 1. The `cis_courses.sql` file. + 2. The `cis_courses_answers` document. + +Submit your files on Canvas. diff --git a/projects/example_public_data_writeup.md b/projects/example_public_data_writeup.md new file mode 100644 index 0000000..7a34b94 --- /dev/null +++ b/projects/example_public_data_writeup.md @@ -0,0 +1,40 @@ +# Cabrillo Courses Example Project + +This project uses data about Cabrillo College gathered from California's [Data Mart](https://datamart.cccco.edu/). The data contains information about all Cabrillo programs and courses. + +## Data + +This project will contain data from the following CSV files, that are turned in with this document. + + - MasterCourseFile.csv - The list of all Cabrillo courses. + - ProgramFile.csv - The list of Cabrillo programs. (A program is a degree or certificate.) + - ProgramCourseFile.csv - The intersection table that maps courses into programs. + +I would like to use this data to better understand Cabrillo's certificates and degrees. + +## Entities and Relationships + +The data is about the following entities: + + - Courses + - Programs (a certificate or degree) + +A program contains required courses. + +## Functional Dependencies and Tables + +Though I have not yet analyzed the data, these are the functional dependencies that I *expect* will be true of this data. Since CSVs cannot enforce functional dependencies the data may need to be manipulated. + +CourseControlNumber -> (CourseID, TOPCode, CreditStatus, MaximumUnits, MinimumUnits, SAMCode, Date) + +ProgramControlNumber -> (Title, TOPCode, AwardType, CreditType, ApprovedDate, Status, InactiveDate) + +ProgramControlNumber ->-> CourseControlNumber + +Based on these functional dependencies I will create the following tables: + +course (CourseControlNumber, CourseID, TOPCode, CreditStatus, MaximumUnits, MinimumUnits, SAMCode, Date)) + +program (ProgramControlNumber, Title, TOPCode, AwardType, CreditType, ApprovedDate, Status, InactiveDate) + +program_course (CourseControlNumber, ProgramControlNumber) diff --git a/projects/using_public_data.md b/projects/using_public_data.md new file mode 100644 index 0000000..df4fed7 --- /dev/null +++ b/projects/using_public_data.md @@ -0,0 +1,38 @@ +# Project: Using Public Data + +California's Open Data Portal is a place where you can get lots of interesting information about the State of California and government programs. In this project you will select a dataset based on your interests and prepare the data to be imported into a schema. + +## Select Your Dataset + +You can use any publicly available dataset for this project. The Open Data Portal has good quality datasets so I recommend looking around these URLs for something that interests you: + +This is a good place for state wide data on a lot of subjects: + +> https://data.ca.gov/ + +Individual state departments also have thier own datasets: + +> https://data.ca.gov/state-portals + +## Data Requirements + +Your schema must be complex enough to meet some requirements. Not all public datasets will meet these requirements, select one that does. You can join multiple datasets if you like. The requirements are: + + 1. You must have at least three tables + 2. You must have at least two foreign key constraints + +## Write-Up + +When you have decided on a dataset write a report that introduces your dataset, the report should explain what your data is and why you want to use it. The write-up must also include: + + 1. An introduction to your project. + 2. A description of the CSV files that you submitted with the assignment. + 3. The entites and relationships in your data + 4. The functional dependencies you *expect* to see. (You don't have to validate the FDs at this stage) + 5. The tables you expect to create. + +[I've written an example](example_public_data_writeup.md) based on the Cabrillo courses labs. Please look at the example and submit something similar. + +## Turn In + +Submit your write-up and your data files. \ No newline at end of file diff --git a/projects/using_public_data_2.md b/projects/using_public_data_2.md new file mode 100644 index 0000000..412994d --- /dev/null +++ b/projects/using_public_data_2.md @@ -0,0 +1,27 @@ +# Project: Public Data Queries + +In the final project for the class you will build a schema using the public dataset you picked in the [Using Public Data](using_public_data.md) project and write queries to show interesting things. + +## Import Your Dataset + +Most of the data that is available is given in spreadsheet form. Import your data into MySQL using the table data import wizard. Use the process you learned in the [Working with Real Data](../labs/realdata_1_cabrillo_import.md) and the [Keys in Real Data](../labs/realdata_2_cabrillo_keys.md) labs to build your schema in SQL. + +Remember, your schema should meet the criteria: + + 1. You must have at least three tables + 2. You must have at least two foreign key constraints + +## Write Queries + +Write two queries that show something interesting in your data. For each query also write a description of what the query shows and why you did it. + +## Export Your Data + +For the final submission export your data from MySQL as an SQL dump file. + +## Turn In + + 1. The SQL dump of your data. + 2. A document with your queries and descriptions. + + \ No newline at end of file diff --git a/welcome.ipynb b/welcome.ipynb new file mode 100644 index 0000000..1dab89c --- /dev/null +++ b/welcome.ipynb @@ -0,0 +1,140 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Introduction to Relational Database Management Systems \n", + "\n", + "The class notes are [Jupyter](http://jupyter.org/) notebooks. Jupyter notebooks let you see and run your SQL queries and mix them with Python to perform data science. \n", + "\n", + "**Notebooks will be added througought the semester**" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Week 1: Welcome \n", + "\n", + "* Ojectives \n", + " * Install MySQL Workbench \n", + " * Get Cloud9 Setup\n", + "* Documentation \n", + " * [Using Jupyter](https://jupyter-notebook.readthedocs.io/en/stable)\n", + " * [Cloud9 User Guide](https://docs.aws.amazon.com/cloud9/latest/user-guide/tutorial.html)\n", + " * [Navigating files and directories in BASH](http://linuxcommand.org/lc3_lts0020.php)\n", + "* Labs\n", + " * [Use Jupyter to Search Airports](Week01/airport_search.ipynb)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Week 2: Working With Lists \n", + "\n", + "* Ojectives \n", + " * Define schema \n", + " * Learn about metadata \n", + " * Understand modification problems\n", + " * Do basic tasks in MySQL Workbench\n", + " * Use an SQL workbook in Jupyter\n", + "* Labs\n", + " * [Use SQL to Search Airports](Week02/query_airports_with_sql.ipynb)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Week 6: SQL Selects\n", + "\n", + " * Objectives \n", + " * Learn the SQL select statment \n", + " * Control the output columns \n", + " * Apply basic where predicates\n", + " * Practice\n", + " * [First SQL Practice](Week06/practice_selects.ipynb)\n", + " \n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Week 7: SQL Sorting, Limiting and Grouping\n", + "\n", + "* Objectives \n", + " * Use the ORDER BY clause\n", + " * Use the LIMIT clause \n", + " * Understand GROUP BY and HAVING\n", + " * Use functions on a group\n", + "* Practice\n", + " * [Ordering, Grouping and Functions](Week07/airports_practice.ipynb)\n", + " * [Population Practice](Week07/population_practice.ipynb)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Week 9: Create, Insert, Update and Delete\n", + "\n", + "* Objectives \n", + " * Use the CREATE statement\n", + " * Insert and delete rows\n", + " * Update rows\n", + "* Practice\n", + " * [Queen Anne Project](Week09/queen_anne_project.ipynb)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Week 10: Multiple Tables and Joins\n", + "\n", + "* Objectives \n", + " * Learn to use subqueries\n", + " * Learn the inner join\n", + "* Practice\n", + " * [Queen Anne Joins](Week10/queen_anne_joins.ipynb)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Week 11: Outer Joins\n", + "\n", + "* Objectives \n", + " * Learn the outer join\n", + "* Practice\n", + " * [Pets Joins](Week11/pets_joins.ipynb)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}