├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── 02_01 ├── sample_web_analytics.sql └── total_revenue_by_region.sql ├── 03_02 └── descriptive_summary.sql ├── 03_03 └── predictive_model.sql ├── 04_02 ├── README.md ├── create-tables.sql ├── db.py ├── index.html └── main.py ├── 04_03 ├── AppDelegate.swift ├── Customer.swift ├── DBHelper.swift ├── LaunchScreen.storyboard ├── Main.storyboard ├── README.md ├── SceneDelegate.swift └── ViewController.swift ├── 04_04 ├── README.md ├── create-tables.sql ├── db.py ├── index.html ├── main.py └── states.html ├── CONTRIBUTING.md ├── LICENSE ├── NOTICE ├── README.md ├── SQL Careers Assessment.pdf └── Skills Inventory Worksheet.pdf /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Codeowners for these exercise files: 2 | # * (asterisk) deotes "all files and folders" 3 | # Example: * @producer @instructor 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 7 | 8 | ## Issue Overview 9 | 10 | 11 | ## Describe your environment 12 | 13 | 14 | ## Steps to Reproduce 15 | 16 | 1. 17 | 2. 18 | 3. 19 | 4. 20 | 21 | ## Expected Behavior 22 | 23 | 24 | ## Current Behavior 25 | 26 | 27 | ## Possible Solution 28 | 29 | 30 | ## Screenshots / Video 31 | 32 | 33 | ## Related Issues 34 | 35 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | .tmp 4 | npm-debug.log 5 | -------------------------------------------------------------------------------- /02_01/sample_web_analytics.sql: -------------------------------------------------------------------------------- 1 | #standardSQL 2 | SELECT 3 | date, 4 | COUNT (DISTINCT visitId) as num_records, 5 | SUM(totals.visits) as num_visits, 6 | SUM(totals.hits) num_hits, 7 | AVG(totals.pageviews) average_page_views, 8 | AVG(totals.transactions) average_transactions, 9 | SUM(totals.totalTransactionRevenue) total_revenue 10 | FROM `bigquery-public-data.google_analytics_sample.ga_sessions*` 11 | GROUP BY date 12 | ORDER BY date 13 | -------------------------------------------------------------------------------- /02_01/total_revenue_by_region.sql: -------------------------------------------------------------------------------- 1 | SELECT geoNetwork.region, 2 | SUM(totals.totalTransactionRevenue) as Total_Revenue 3 | FROM 4 | `bigquery-public-data.google_analytics_sample.ga_sessions_20170801` 5 | WHERE geoNetwork.region IS NOT NULL 6 | GROUP BY geoNetwork.region 7 | ORDER BY Total_Revenue DESC 8 | -------------------------------------------------------------------------------- /03_02/descriptive_summary.sql: -------------------------------------------------------------------------------- 1 | 2 | SELECT 3 | SUMMARY_1.MEASURE as MEASURE, 4 | ST_DEV, 5 | AVERAGE_TOTAL_ORDER, 6 | MIN_TOTAL_DUE, 7 | PERCENTILE_25, 8 | MEDIAN, 9 | PERCENTILE_75, 10 | MAX_TOTAL_DUE 11 | 12 | FROM 13 | (SELECT 'TotalDue' as MEASURE, stddev(TotalDue) as ST_DEV, 14 | avg(TotalDue) as AVERAGE_TOTAL_ORDER, 15 | max(TotalDue) as MAX_TOTAL_DUE, 16 | min(TotalDue) as MIN_TOTAL_DUE 17 | from `sql-careers.HPlusSports.orders`) as SUMMARY_1, 18 | 19 | (SELECT 'TotalDue' as MEASURE, 20 | PERCENTILE_CONT(TotalDue, 0.25) OVER () AS PERCENTILE_25, 21 | PERCENTILE_CONT(TotalDue, 0.5) OVER () AS MEDIAN, 22 | PERCENTILE_CONT(TotalDue, 0.75) OVER () AS PERCENTILE_75 23 | FROM 24 | (SELECT TotalDue FROM `sql-careers.HPlusSports.orders`) as Total 25 | LIMIT 26 | 1) AS SUMMARY_2 27 | WHERE SUMMARY_1.MEASURE = SUMMARY_2.MEASURE 28 | -------------------------------------------------------------------------------- /03_03/predictive_model.sql: -------------------------------------------------------------------------------- 1 | -- Build a Forecasting Model based on Historical Product Sales data 2 | 3 | CREATE OR REPLACE VIEW HPlusSports.forecast_training_data AS 4 | (SELECT orders.OrderDate, 5 | ProductCode, 6 | total_products_sold 7 | FROM `sql-careers.HPlusSports.orders` as orders, 8 | (SELECT OrderID, 9 | p.ProductCode, 10 | SUM(Quantity) as total_products_sold 11 | FROM `sql-careers.HPlusSports.order_item` i ,`sql-careers.HPlusSports.products` p 12 | where i.ProductID = p.ProductID 13 | group by ORDERID, ProductCode) as products_sold 14 | WHERE orders.OrderID = products_sold.OrderID); 15 | 16 | 17 | -- Create A Time Series Based Model 18 | CREATE OR REPLACE MODEL HPlusSports.forecast_model 19 | OPTIONS( 20 | MODEL_TYPE='ARIMA', 21 | TIME_SERIES_TIMESTAMP_COL='OrderDate', 22 | TIME_SERIES_DATA_COL='total_products_sold', 23 | TIME_SERIES_ID_COL='ProductCode', 24 | HOLIDAY_REGION='US' 25 | ) AS 26 | SELECT OrderDate, ProductCode,total_products_sold 27 | FROM `sql-careers.HPlusSports.forecast_training_data` 28 | 29 | -- Evaluate the Model 30 | SELECT * FROM 31 | ML.EVALUATE(MODEL `sql-careers.HPlusSports.forecast_model`); 32 | 33 | 34 | -- Make Predictions for the next 30 days at a confidence interval of 90% 35 | SELECT * 36 | FROM 37 | ML.FORECAST(MODEL HPlusSports.forecast_model, 38 | STRUCT(30 AS horizon, 0.9 AS confidence_level)); 39 | 40 | -- Create a view to build visualization 41 | CREATE OR REPLACE VIEW HPlusSports.forecast_datastudio AS ( 42 | SELECT 43 | OrderDate AS timestamp, 44 | ProductCode, 45 | total_products_sold as history_value, 46 | NULL AS forecast_value, 47 | NULL AS prediction_interval_lower_bound, 48 | NULL AS prediction_interval_upper_bound 49 | FROM 50 | HPlusSports.forecast_training_data 51 | UNION ALL 52 | SELECT 53 | EXTRACT(DATE 54 | FROM 55 | forecast_timestamp) AS timestamp, 56 | ProductCode, 57 | NULL AS history_value, 58 | forecast_value, 59 | prediction_interval_lower_bound, 60 | prediction_interval_upper_bound 61 | FROM 62 | ML.FORECAST(MODEL `sql-careers.HPlusSports.forecast_model`, 63 | STRUCT(30 AS horizon, 0.9 AS confidence_level)) 64 | ORDER BY timestamp 65 | ); 66 | 67 | SELECT * FROM `sql-careers.HPlusSports.forecast_datastudio`; 68 | -------------------------------------------------------------------------------- /04_02/README.md: -------------------------------------------------------------------------------- 1 | For more information on setting up the Google Cloud SDK and AppEngine, visit: https://cloud.google.com/appengine/docs/standard/python3/quickstart 2 | 3 | Quickstart for Cloud SQL for MySQL: https://cloud.google.com/sql/docs/mysql/quickstart 4 | 5 | -------------------------------------------------------------------------------- /04_02/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table customers ( 2 | CustomerID INT NOT NULL, 3 | FirstName VARCHAR(255), 4 | LastName VARCHAR(255), 5 | Email VARCHAR(255), 6 | Phone VARCHAR(255), 7 | Address VARCHAR(255), 8 | City VARCHAR(255), 9 | State VARCHAR(255), 10 | Zipcode VARCHAR(255), 11 | PRIMARY KEY(CustomerID) 12 | ); 13 | 14 | create table census_state_pop ( 15 | statename VARCHAR(255), 16 | pop VARCHAR(255), 17 | code VARCHAR(255) 18 | ); -------------------------------------------------------------------------------- /04_02/db.py: -------------------------------------------------------------------------------- 1 | import os 2 | import pymysql 3 | from flask import jsonify, request 4 | import json 5 | from urllib.request import urlopen 6 | import urllib.error 7 | 8 | db_user = os.environ.get('CLOUD_SQL_USERNAME') 9 | db_password = os.environ.get('CLOUD_SQL_PASSWORD') 10 | db_name = os.environ.get('CLOUD_SQL_DATABASE_NAME') 11 | db_connection_name = os.environ.get('CLOUD_SQL_CONNECTION_NAME') 12 | acs_api_key = os.environ.get('ACS_KEY') 13 | 14 | def open_connection(): 15 | unix_socket = '/cloudsql/{}'.format(db_connection_name) 16 | try: 17 | if os.environ.get('GAE_ENV') == 'standard': 18 | conn = pymysql.connect(user=db_user, password=db_password, 19 | unix_socket=unix_socket, db=db_name, 20 | cursorclass=pymysql.cursors.DictCursor 21 | ) 22 | except pymysql.MySQLError as e: 23 | print(e) 24 | 25 | return conn 26 | 27 | 28 | def get_customers(): 29 | conn = open_connection() 30 | with conn.cursor() as cursor: 31 | sql = 'SELECT * FROM customers LIMIT 50;' 32 | result = cursor.execute(sql) 33 | customers = cursor.fetchall() 34 | 35 | if result > 0: 36 | customers_json = jsonify(customers) 37 | else: 38 | customers_json = 'No Customers in the Database' 39 | conn.close() 40 | return customers_json 41 | 42 | 43 | def add_state_census(name, pop,code): 44 | conn = open_connection() 45 | insert_sql = """INSERT INTO census_state_pop (statename, pop, code) 46 | VALUES (%s, %s, %s)""" 47 | with conn: 48 | cursor = conn.cursor() 49 | cursor.execute(insert_sql,(name,pop,code)) 50 | conn.commit() 51 | conn.close() 52 | return 53 | 54 | def new_census_data(): 55 | try: 56 | url = "https://api.census.gov/data/2010/dec/sf2?get=NAME,HCT001001&for=state:*" 57 | response = urlopen(url) 58 | response_data = json.loads(response.read()) 59 | return response_data 60 | 61 | except urllib.error.HTTPError as e: 62 | print(e.__dict__) 63 | except urllib.error.URLError as e: 64 | print(e.__dict__) 65 | 66 | 67 | def load_census_data(): 68 | response = new_census_data() 69 | conn = open_connection() 70 | insert_sql = """INSERT INTO census_state_pop (statename, pop, code) 71 | VALUES (%s, %s, %s)""" 72 | with conn: 73 | cursor = conn.cursor() 74 | for i, item in enumerate(response): 75 | if i > 0: 76 | name = item[0] 77 | pop = item[1] 78 | code = item[2] 79 | print('Name: ',name,' Population: ',pop, 'Code: ',code) 80 | cursor.execute(insert_sql,(name,pop,code)) 81 | conn.commit() 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /04_02/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
First Name | 22 |Last Name | 23 |Phone | 25 |Address | 26 |City | 27 |State | 28 |Zip | 29 ||
---|---|---|---|---|---|---|---|
{{row["FirstName"]}} | 35 |{{row["LastName"]}} | 36 |{{row["Email"]}} | 37 |{{row["Phone"]}} | 38 |{{row["Address"]}} | 39 |{{row["City"]}} | 40 |{{row["State"]}} | 41 |{{row["Zipcode"]}} | 42 |