7 Beginner to Intermediate SQL Interview Questions for Data Analytics roles
By: Edoardo Romani
Tags: MySQL, Sql, Interview Questions, Data Analytics, Relational Databases

(Notes: All opinions are my own)

Introduction

Good SQL knowledge is required across most analytics roles, and is a popular subject of coding tests. No matter the role, SQL skills are in demand, and the stronger your command of the language, the better your chances to snatch the position you are looking for.

The aim of this article is to give you a practical set of example questions to practice with. It is mostly beginner-to-intermediate oriented, but some of these questions are not far from what you would be put in front of during an interview.

Hope you will find them useful for your preparation.

N.B: there are potentially multiple ways to answer the below questions. The answers provided here represent just one of the alternatives. Feel free to implement your own logic as you reason through them.

The data

You are going to be working with a small sample of social-media like data. There are two tables, users, which contains basic information about people profiles, and follows, which lists which users follow another given user.

The theme of this data is the magical world of Harry Potter, in which users are taken from various characters of the Harry Potter Saga.

The users table will thus look like something like the below, with the user_id, first_name,last_name and house columns.

user_id, first_name, last_name, house

1,Harry,Potter,Gryffindor

2,Ron,Wesley,Gryffindor

3,Hermonie,Granger,Gryffindor

4,Ginny,Weasley,Gryffindor

5,Draco,Malfoy,Slytherin

6,Tom,Riddle,Slytherin

7,Luna,Lovegood,Ravenclaw

8,Cho,Chang,Ravenclaw

9,Cedric,Diggory,Hufflepuff

The follows table will then report information of which two user ids form a relationship in which the former follows the latter. The columns will thus be user_id, follows (the user_id of the user being followed), and the date in which the “following” relationship was created.

user_id,follows,date

1,2,1993-09-01

2,1,1989-01-01

3,1,1993-07-01

2,3,1994-10-10

3,2,1995-03-01

4,2,1988-08-08

4,1,1988-08-08

1,4,1994-04-02

1,5,2000-01-01

5,1,2000-01-02

5,6,1986-01-10

7,1,1990-02-02

1,7,1996-10-01

1,8,1993-09-03

8,1,1995-09-01

8,9,1995-09-01

9,8,1996-01-10

7,8,1993-09-01

3,9,1996-05-30

4,9,1996-05-30

Let’s now see how to create this data programmatically in order to be able to run queries against it.

Set-up: Running MYSQL queries on goormIDE

In order to run your queries, you can make use of the goorm.io IDE.

It’s a great resource I bumped into while refreshing my SQL knowledge taking “The Ultimate MySQL Bootcamp: Go from SQL Beginner to Expert” course on Udemy.

You can refer to the link below to get signed up and up & running with a new container, within which you will be able to start and shut databases, and run SQL scripts.

Goorm.io Signup Instructions

(You’ll find some references to the course in the instructions below. You can easily follow them even if you are not effectively taking the course, as this will get you equally set up to run your SQL scripts from a goorm.io container)

Once you are set up, it is now time to create the Harry Potter database and start querying!

Database & Table Creation

First off, let’s create a database to store our tables. You can name it however you like, I named it social.

Then, the users and the follows table are created, with the data types specified below. The user_id column acts as the primary key and foreign key across users and follows, linking the two tables together.

DROP DATABASE IF EXISTS social;

CREATE DATABASE social;

USE social; CREATE TABLE users(

user_id INTEGER PRIMARY KEY,

first_name TEXT NOT NULL,

last_name TEXT,

house TEXT); CREATE TABLE follows(

user_id INTEGER,

follows INTEGER,

date_created DATE,

FOREIGN KEY (user_id) REFERENCES users(user_id),

FOREIGN KEY (follows) REFERENCES users(user_id));

Once this is done, it’s time to insert the data you saw above. You can do this with the INSERT INTO [table] command. Feel free to copy the below into your script and run it in the MYSQL container via the source name_of_sql_file.sql command.

INSERT INTO users (user_id,first_name,last_name,house

) VALUES (1,"Harry","Potter","Gryffindor"),

(2,"Ron","Wesley","Gryffindor"),

(3,"Hermonie","Granger","Gryffindor"),

(4,"Ginny","Weasley","Gryffindor"),

(5,"Draco","Malfoy","Slytherin"),

(6,"Tom","Riddle","Slytherin"),

(7,"Luna","Lovegood","Ravenclaw"),

(8,"Cho","Chang","Ravenclaw"),

(9,"Cedric","Diggory","Hufflepuff"); INSERT INTO follows (user_id,follows,date_created)

VALUES (1,2,STR_TO_DATE("1993-09-01", '%Y-%m-%d')),

(2,1,STR_TO_DATE("1989-01-01",'%Y-%m-%d')),

(3,1,STR_TO_DATE("1993-07-01",'%Y-%m-%d')),

(2,3,STR_TO_DATE("1994-10-10",'%Y-%m-%d')),

(3,2,STR_TO_DATE("1995-03-01",'%Y-%m-%d')),

(4,2,STR_TO_DATE("1988-08-08",'%Y-%m-%d')),

(4,1,STR_TO_DATE("1988-08-08",'%Y-%m-%d')),

(1,4,STR_TO_DATE("1994-04-02",'%Y-%m-%d')),

(1,5,STR_TO_DATE("2000-01-01",'%Y-%m-%d')),

(5,1,STR_TO_DATE("2000-01-02",'%Y-%m-%d')),

(5,6,STR_TO_DATE("1986-01-10",'%Y-%m-%d')),

(7,1,STR_TO_DATE("1990-02-02",'%Y-%m-%d')),

(1,7,STR_TO_DATE("1996-10-01",'%Y-%m-%d')),

(1,8,STR_TO_DATE("1993-09-03",'%Y-%m-%d')),

(8,1,STR_TO_DATE("1995-09-01",'%Y-%m-%d')),

(8,9,STR_TO_DATE("1995-09-01",'%Y-%m-%d')),

(9,8,STR_TO_DATE("1996-01-10",'%Y-%m-%d')),

(7,8,STR_TO_DATE("1993-09-01",'%Y-%m-%d')),

(3,9,STR_TO_DATE("1996-05-30",'%Y-%m-%d')),

(4,9,STR_TO_DATE("1996-05-30",'%Y-%m-%d'));

With the database, tables and data all set up, let’s start querying!

Question 1

How many users are there in each house?

To answer this question, you can make use of the COUNT function and the GROUP BY column to aggregate the number of users each house features in the users table.

QUERY

SELECT house,

count(*)as num_students

FROM users

GROUP BY house;

RESULT

Source: Author

Question 2

List all following links that were created before September 1st, 1993

To answer this question, you can make use of the WHERE statement to filter the follows table for all rows created before the specified date.

QUERY

SELECT *

FROM follows

WHERE date_created<"1993-09-01";

RESULT

Source: Author

Question 3

List all the following links established before September 1st 1993, but this time use the users first names

This question is equivalent to question 2, except you are now tasked to linkthe user_id of the follower and the followee to their first names, which are present in the users table.

To do this, you can use a double join of the follows table with the users table, thus sourcing both the first name of the user_id column in the follows table and the first name of the follows column in the follows table.

The WHERE statement remains to make sure you filter for the links established before September 1st 1993. You can also make use of aliases to rename your output results.

QUERY

SELECT u.first_name as follower,

u2.first_name as followee,

date_created

FROM follows

JOIN users as u ON follows.user_id=u.user_id

JOIN users as u2 ON follows.follows=u2.user_id

WHERE date_created<"1993-09-01";

RESULT

Source: Author

Question 4

Give a count of how many people followed each user as of 1999–12–31. Give the result in term of “user full name, number of followers”

With this question you are basically interested to know who’s the user with the most followers. You can solve this by grouping the data by the follows column in the follows table, and then counting how many users follow that particular user_id.

The WHERE statement filters by date and the JOIN with the users table to bring in each followee’s first name. To create the full name, the CONCAT statement is used to merge the first_name and last_name column of the users table, and results are then sorted by the number of followers.

QUERY

SELECT concat(first_name," ",last_name) as full_name,

COUNT(*) as number_of_followers

FROM follows

JOIN users ON follows.follows=users.user_id

WHERE date_created<"1999-12-31"

GROUP BY full_name

ORDER BY number_of_followers DESC;

RESULT

Source: Author.

As expected, Harry Potter comes out on top as the most popular user!

Question 5

List the number of users each user follows

This question complements question 4 as it asks for the reverse relationship. You can solve it via a similar logic by using the user_id column in the follows table to bring in first names of users, and then grouping the data by the same column while counting the number of rows in the follows table.

As before, you can order the results to get a view of who’s most active in following others. Again, Harry Potter comes out on top!

QUERY

SELECT first_name as user,

count(follows) as total_people_followed

FROM follows

JOIN users ON follows.user_id=users.user_id

GROUP BY user

ORDER by total_people_followed DESC;

RESULT

Source: Author

Question 6

List all rows from follows where someone from one house follows someone from a different house. Give the result with user names.

This question asks you to list all relationships between users from different houses. The logic you can use is to use the user_id and follows columns respectively to bring in name and house information for each row in the follows table.

Once that is complete, you can filter for rows in which the follower and the followee do not below to the same house. The use of aliases in this query can help you out in clarifying each column as you add to the final result.

QUERY

SELECT u.first_name as follower,

u2.first_name as followee,

u.house as follower_house,

u2.house as followee_house

FROM follows

JOIN users as u ON follows.user_id=u.user_id

JOIN users as u2 ON follows.follows=u2.user_id

WHERE u.house!=u2.house;

RESULT

Source: Author

Question 7

List all unrequited followings (i.e. where A follows B but B does not follow A)

To solve this query, you can:

list out all follower-followee pairs from the follows table as [Concat(follows.user_id,” “,follows.follows)]

identify the opposite following relationships by reversing the pair as [Concat(follows.follows,” “,follows.user_id)]

keep only the opposite following relationships which are not featured in the original list of follower-followee pairs (that is, the follows table)

The rest of the query joins back to the users table to bring in name information as to arrange it in the final output as “name of the user” + “name of the user which the first user does not follow back”.

This way, you can identify the 6 relationships in our database in which the user on the left does not follow the user on the right, given that the user on the right follows the user on the left. (i.e. “Harry does not follow Hermonie even though Hermonie follows Harry”)

QUERY

SELECT u.first_name as person,

u2.first_name as does_not_follow_back

FROM follows

JOIN users as u on follows.follows=u.user_id

JOIN users as u2 on follows.user_id=u2.user_id

WHERE Concat(follows.follows," ",follows.user_id) NOT IN (SELECT Concat(follows.user_id," ",follows.follows) as relationship FROM follows);

RESULT

Source: Author

Summary

Hope you found these exercise useful. As mentioned, feel free to implement your own logic as with SQL there are usually multiple ways to get to a given result.

Thanks for reading!