‘SQL for Data Science’ Course - Week 4 Assignment


This is a 2-part assignment. In the first part, you are asked a series of questions that will help you profile and understand the data just like a data scientist would. For this first part of the assignment, you will be assessed both on the correctness of your findings, as well as the code you used to arrive at your answer. You will be graded on how easy your code is to read, so remember to use proper formatting and comments where necessary.

In the second part of the assignment, you are asked to come up with your own inferences and analysis of the data for a particular research question you want to answer. You will be required to prepare the dataset for the analysis you choose to do. As with the first part, you will be graded, in part, on how easy your code is to read, so use proper formatting and comments to illustrate and communicate your intent as required.


The database that was used is the CHINOOK database: click to access


##Part 1: Yelp Dataset Profiling and Understanding

  1. Profile the data by finding the total number of records for each of the tables below:
  1. Attribute table = 10000 records
  2. Business table = 10000 records
  3. Category table = 10000 records
  4. Checkin table = 10000 records
  5. elite_years table = 10000 records
  6. friend table = 10000 records
  7. hours table = 10000 records
  8. photo table = 10000 records
  9. review table = 10000 records
  10. tip table = 10000 records
  11. user table = 10000 records



  1. Find the total distinct records by either the foreign key or primary key for each table. If two foreign keys are listed in the table, please specify which foreign key.
  1. Business =10000 records for id
  2. Hours = 2052 records for hours, 1562 records for business_id
  3. Category = 712 records for category / 2643 records for business_id
  4. Attribute = 39 records for name / 1115 records for business_id
  5. Review = 10000 records for id
  6. Checkin = 493 records for business_id
  7. Photo = 6493 records for business_id
  8. Tip = 3979 records for business_id
  9. User = 10000 records for id
  10. Friend = 11 records for user_id
  11. Elite_years = 2780 records for user_id

Note: Primary Keys are denoted in the ER-Diagram with a yellow key icon.



3. Are there any columns with null values in the Users table? Indicate “yes,” or “no.”

Answer: NO


SQL code used to arrive at answer:
SELECT COUNT(*)
FROM user
WHERE id IS NULL OR  
name IS NULL OR  
review_count IS NULL OR  
yelping_since IS NULL OR  
useful IS NULL OR  
funny IS NULL OR  
cool IS NULL OR  
fans IS NULL OR  
average_stars IS NULL OR  
compliment_hot IS NULL OR  
compliment_more IS NULL OR  
compliment_profile IS NULL OR  
compliment_cute IS NULL OR  
compliment_list IS NULL OR  
compliment_note IS NULL OR  
compliment_plain IS NULL OR  
compliment_cool IS NULL OR  
compliment_funny IS NULL OR  
compliment_writer IS NULL OR  
compliment_photos IS NULL


4. For each table and column listed below, display the smallest (minimum), largest (maximum), and average (mean) value for the following fields:

i. Table: Review, Column: Stars

    min:1       max:5       avg:3.71
    

ii. Table: Business, Column: Stars

    min:1       max:5       avg:3.65
    

iii. Table: Tip, Column: Likes

    min:0       max:2       avg:0.0144
    

iv. Table: Checkin, Column: Count

    min:1       max:53      avg:1.94
    

v. Table: User, Column: Review_count

    min:0       max:2000    avg:24.3
    



  1. List the cities with the most reviews in descending order:

    SQL code used to arrive at answer:  
    SELECT city, SUM(review_count) as nr_reviews  
    FROM business  
    GROUP by city  
    ORDER by nr_reviews desc

+—————–+————+
| city | nr_reviews |
+—————–+————+
| Las Vegas | 82854 |
| Phoenix | 34503 |
| Toronto | 24113 |
| Scottsdale | 20614 |
| Charlotte | 12523 |
| Henderson | 10871 |
| Tempe | 10504 |
| Pittsburgh | 9798 |
| Montr?al | 9448 |
| Chandler | 8112 |
| Mesa | 6875 |
| Gilbert | 6380 |
| Cleveland | 5593 |
| Madison | 5265 |
| Glendale | 4406 |
| Mississauga | 3814 |
| Edinburgh | 2792 |
| Peoria | 2624 |
| North Las Vegas | 2438 |
| Markham | 2352 |
| Champaign | 2029 |
| Stuttgart | 1849 |
| Surprise | 1520 |
| Lakewood | 1465 |
| Goodyear | 1155 |
+—————–+————+ (Output limit exceeded, 25 of 362 total rows shown)



6. Find the distribution of star ratings to the business in the following cities:
i. Avon

SQL code used to arrive at answer:
SELECT count(stars) as Nr_businesses, city, stars
FROM business
WHERE city=“Avon”
GROUP BY stars
Copy and Paste the Resulting Table Below (2 columns - star rating and count):
+———————+——-+
| count_nr_businesses | stars |
+———————+——-+
| 1 | 1.5 |
| 2 | 2.5 |
| 3 | 3.5 |
| 2 | 4.0 |
| 1 | 4.5 |
| 1 | 5.0 |
+———————+——-+


  1. Beachwood

SQL code used to arrive at answer:
SELECT count(stars) as Nr_businesses, city, stars
FROM business
WHERE city=“Beachwood”
GROUP BY stars
Copy and Paste the Resulting Table Below (2 columns - star rating and count):
+———————+——-+
| count_nr_businesses | stars |
+———————+——-+
| 1 | 2.0 |
| 1 | 2.5 |
| 2 | 3.0 |
| 2 | 3.5 |
| 1 | 4.0 |
| 2 | 4.5 |
| 5 | 5.0 |
+———————+——-+


7. Find the top 3 users based on their total number of reviews:  
SQL code used to arrive at answer:

SELECT name, sum(review_count) as total_nr_reviews


FROM user
GROUP BY name
ORDER BY by total_nr_reviews desc limit 3
Copy and Paste the Result Below:
+——–+——————+
| name | total_nr_reviews |
+——–+——————+
| Nicole | 2397 |
| Sara | 2253 |
| Gerald | 2034 |
+——–+——————+  

  1. Does posting more reviews correlate with more fans?
    Please explain your findings and interpretation of the results:

    The number of users ranked #6 to #12 in terms of fans, have posted < reviews than the top 5 users in terms of # of reviews:
    +———-+———+———+
    | name | reviews | totfans |
    +———-+———+———+
    | John | 102 | 46 |
    | David | 90 | 25 |
    | Chris | 74 | 52 |
    | Mike | 74 | 119 |
    | Michael | 72 | 34 |
    | Jennifer | 63 | 86 |
    | Mark | 59 | 156 |
    | Lisa | 58 | 207 |
    | Melissa | 58 | 104 |
    | Sarah | 55 | 100 |
    | Alex | 54 | 22 |
    | James | 48 | 86 |
    | Jessica | 45 | 116 |
    | Ryan | 45 | 24 |
    | J | 43 | 13 |
    | Michelle | 43 | 133 |
    | Andrew | 41 | 114 |
    | Kevin | 41 | 20 |
    | Mary | 41 | 18 |
    | Amanda | 40 | 26 |
    | Ashley | 40 | 16 |
    | Brian | 40 | 72 |
    | Karen | 40 | 123 |
    | Laura | 39 | 38 |
    | Robert | 39 | 9 |
    +———-+———+———+ (Output limit exceeded, 25 of 3454 total rows shown)


SELECT id, name, sum(review_count) as reviews, sum(fans) as totfans
FROM user
GROUP by id
ORDER by reviews desc


  1. Are there more reviews with the word “love” or with the word “hate” in them?
    Answer:
    There are more reviews with the word “love” (1780) than “hate” (232)  
    SQL code used to arrive at answer:
    SELECT COUNT()
    FROM review
    WHERE text LIKE “%love%”

    SELECT COUNT(
    )
    FROM review
    WHERE text LIKE “%hate%”


  2. Find the top 10 users with the most fans:
    select id, name, sum(fans) as total_nr_fans
    from user
    group by id
    order by total_nr_fans desc limit 10

    Copy and Paste the Result Below:
    +————————+———–+—————+
    | id | name | total_nr_fans |
    +————————+———–+—————+
    | -9I98YbNQnLdAmcYfb324Q | Amy | 503 |
    | -8EnCioUmDygAbsYZmTeRQ | Mimi | 497 |
    | –2vR0DIsmQ6WfcSzKWigw | Harald | 311 |
    | -G7Zkl1wIWBBmD0KRy_sCw | Gerald | 253 |
    | -0IiMAZI2SsQ7VmyzJjokQ | Christine | 173 |
    | -g3XIcCb2b-BD0QBCcq2Sw | Lisa | 159 |
    | -9bbDysuiWeo2VShFJJtcw | Cat | 133 |
    | -FZBTkAZEXoP7CYvRV2ZwQ | William | 126 |
    | -9da1xk7zgnnfO1uTVYGkA | Fran | 124 |
    | -lh59ko3dxChBSZ9U7LfUw | Lissa | 120 |
    +————————+———–+—————+  
     

Part 2: Inferences and Analysis


1. Pick one city and category of your choice and group the businesses in that city or category by their overall star rating. Compare the businesses with 2-3 stars to the businesses with 4-5 stars and answer the following questions. Include your code.

I chose Phoenix & the ‘restaurants’ category. There are only 5 distinct business under this category though. Grouped 3 businesses under the 2 to 3.5 stars, the other 2 businesses were 4 & 4.5 stars respectively.

i. Do the two groups you chose to analyze have a different distribution of hours?
The different distribution is only significant between the 2-star restaurant (opens from early morning to midnight) versus the 4.5 stars restaurant that opens only from 10am to 6pm. There are no differences between the other restaurants.
ii. Do the two groups you chose to analyze have a different number of reviews?
It is difficult to analyze due to the low # of businesses in the dataset for this particular group. There appears to be a correlation between low number of reviews and low star rating (2-star restaurant only has 8 reviews).

iii. Are you able to infer anything from the location data provided between these two groups? Explain.
Not really. The zipcodes for all 5 businesses are all distinct. An additional analysis would need to place the GPS location in a map chart to see if the business are located in avenues or high-traffic streets.

SQL code used for analysis:
SELECT bus.id, bus.name, bus.city, cat.category, bus.stars, bus.review_count, hr.hours, bus.postal_code, bus.latitude, bus.longitude
FROM business bus
INNER JOIN category cat
ON bus.id = cat.business_id
INNER JOIN hours hr
ON bus.id = hr.business_id
WHERE bus.city = ‘Phoenix’ and cat.category=‘Restaurants’
ORDER BY by stars (/* order by “stars desc”, to see the bottom of the subset */)

 
2. Group business based on the ones that are open and the ones that are closed. What differences can you find between the ones that are still open and the ones that are closed? List at least two differences and the SQL code you used to arrive at your answer.  

i. Difference 1:
The businesses that are OPEN tend to have > reviews than the ones that are CLOSED.
Open business: AVG(review_count) = 31.76
Closed business: AVG(review_count) = 23.2


ii. Difference 2:
The average star rating is higher for businesses that are OPEN than for businesses that are CLOSED.
Open: AVG(stars) = 3.68
Closed: AVG(stars) = 3.52


SQL code used for analysis:
SELECT COUNT(DISTINCT(id)), AVG(review_count), SUM(review_count), AVG(stars), is_open
FROM business
GROUP BY is_open  

  1. For this last part of your analysis, you are going to choose the type of analysis you want to conduct on the Yelp dataset and are going to prepare the data for analysis.
    Ideas for analysis include: Parsing out keywords and business attributes for sentiment analysis, clustering businesses to find commonalities or anomalies between them, predicting the overall star rating for a business, predicting the number of fans a user will have, and so on. These are just a few examples to get you started, so feel free to be creative and come up with your own problem you want to solve. Provide answers, in-line, to all of the following:
  1. Indicate the type of analysis you chose to do:
    We want to try to analyse which factors contribute to businesses remaining open (as opposed to closing definitively).
     
  2. Write 1-2 brief paragraphs on the type of data you will need for your analysis and why you chose that data:
    I want to help businesses understand the importance of various factors that contribute to predict if their business will stay open.
    These factors in this case will be the business star rating, location, attributes, hours open, # of reviews.
    We will gather the latitude and longitude as well as the complete address to make processing easier later on.
    Categories will be used to better distinguish between different types of businesses.
    The “is_open” column will flag whether the business in question is open, or has closed permanently.


iv. Provide the SQL code you used to create your final dataset:

SELECT B.id as Business_ID,
B.name as Business_Name,
B.address,
B.city,
B.state,
B.postal_code,
B.latitude,
B.longitude,
B.review_count as Nr_reviews,
B.stars as Star_Rating,
MAX(CASE WHEN H.hours LIKE “%monday%” THEN TRIM(H.hours,‘%MondayTuesWednesThursFriSatSun|%’)
END) AS open_hours_Mon,
MAX(CASE wHEN H.hours LIKE “%tuesday%” THEN TRIM(H.hours,‘%MondayTuesWednesThursFriSatSun|%’)
END) AS open_hours_Tue,
MAX(CASE WHEN H.hours LIKE “%wednesday%” THEN TRIM(H.hours,‘%MondayTuesWednesThursFriSatSun|%’) END) AS open_hours_Wed,
MAX(CASE WHEN H.hours LIKE “%thursday%” THEN TRIM(H.hours,‘%MondayTuesWednesThursFriSatSun|%’)
END) AS open_hours_Thur, MAX(CASE WHEN H.hours LIKE “%friday%” THEN TRIM(H.hours,‘%MondayTuesWednesThursFriSatSun|%’)
END) AS open_hours_Fri, MAX(CASE WHEN H.hours LIKE “%saturday%” THEN TRIM(H.hours,‘%MondayTuesWednesThursFriSatSun|%’)
END) AS open_hours_Sat, MAX(CASE WHEN H.hours LIKE “%sunday%” THEN TRIM(H.hours,‘%MondayTuesWednesThursFriSatSun|%’)
END) AS open_hours_Sun,
GROUP_CONCAT(DISTINCT(C.category)) AS categories,
GROUP_CONCAT(DISTINCT(A.name)) AS attributes,
B.is_open
FROM business B
INNER JOIN hours H
ON B.id = H.business_id
INNER JOIN category C
ON B.id = C.business_id
INNER JOIN attribute A
ON B.id = A.business_id
GROUP BY B.id

  1. Output of your finished dataset:
    +—————————————————————————————-+———+ | Business_ID | Business_Name | address | city | state | postal_code | latitude | longitude | Nr_reviews | Star_Rating | open_hours_Mon | open_hours_Tue | open_hours_Wed | open_hours_Thur | open_hours_Fri | open_hours_Sat | open_hours_Sun | categories | attributes | is_open | ———————————————+———+
    | -0DET7VdEQOJVJ_v6klEug | Flaming Kitchen | 3235 York Regional Road 7 | Markham | ON | L3R 3P9 | 43.8484 | -79.3487 | 25 | 3.0 | 12:00-23:00 | 12:00-23:00 | 12:00-23:00 | 12:00-23:00 | 12:00-23:00 | 12:00-23:00 | 12:00-23:00 | Asian Fusion,Restaurants | RestaurantsTableService,GoodForMeal,Alcohol,Caters,HasTV,RestaurantsGoodForGroups,NoiseLevel,WiFi,RestaurantsAttire,RestaurantsReservations,OutdoorSeating,RestaurantsPriceRange2,BikeParking,RestaurantsDelivery,Ambience,RestaurantsTakeOut,GoodForKids,BusinessParking | 1 |-2HjuT4yjLZ3b5f_abD87Q | Freemans Car Stereo | 4821 South Blvd | Charlotte | NC | 28217 | 35.1727 | -80.8755 | 8 | 3.5 | 9:00-19:00 | 9:00-19:00 | 9:00-19:00 | 9:00-19:00 | 9:00-19:00 | 9:00-17:00 | None | Electronics,Shopping,Automotive,Car Stereo Installation | BusinessAcceptsCreditCards,RestaurantsPriceRange2,BusinessParking,WheelchairAccessible | 1 |
    | -CdstAUdEvci8GeJG8owpQ | Motors & More | 2315 Highland Dr | Las Vegas | NV | 89102 | 36.1465 | -115.167 | 7 | 5.0 | 7:00-17:00 | 7:00-17:00 | 7:00-17:00 | 7:00-17:00 | 7:00-17:00 | 8:00-12:00 | None | Home Services,Solar Installation,Heating & Air Conditioning/HVAC | BusinessAcceptsCreditCards,BusinessAcceptsBitcoin,ByAppointmentOnly | 1 |
    | -K4gAv8_vjx8-2BxkVeRkA | Baby Cakes | 4145 Erie St | Willoughby | OH | 44094 | 41.6399 | -81.4064 | 5 | 3.5 | None | 11:00-17:00 | 11:00-17:00 | 11:00-20:00 | 11:00-17:00 | 10:00-17:00 | None | Bakeries,Food | BusinessAcceptsCreditCards,RestaurantsTakeOut,WheelchairAccessible,RestaurantsDelivery | 1 |

| -PtTGvWsckUL8tTutHr6Ew | Snip-its Rocky River | 21609 Center Ridge Rd | Rocky River | OH | 44116 | 41.4595 | -81.8587 | 18 | 2.5 | 10:00-19:00 | 10:00-19:00 | 10:00-19:00 | 10:00-19:00 | 10:00-19:00 | 9:00-17:30 | 10:00-16:00 | Beauty & Spas,Hair Salons | BusinessAcceptsCreditCards,RestaurantsPriceRange2,GoodForKids,BusinessParking,ByAppointmentOnly | 1 |
| 1 |
+————————+————————-+—————–+—————+——-+—————–+———+
(Output limit exceeded, 25 of 70 total rows shown)