Data Analysts and Data Scientists at Fastenal write SQL queries to dive deep into sales data, allowing them to track product performance and spot trends in customer buying behavior. It helps them make smart choices about inventory and improve delivery routes to ensure products arrive on time, which is why Fastenal tests jobseekers with SQL interview questions.
To help you prep for the Fastenal SQL interview, here's 9 Fastenal SQL interview questions – scroll down to start solving them!
As a data analyst of Fastenal, you are asked to calculate the average quantity of each product sold on a monthly basis in 2022. Your task is creating a SQL query that determines the average quantity of each product sold in each month.
Fastenal Company is an American industrial supply company, thus, assume that the following table, sales
, represents the amount of each product sold each day.
sales
Example Input:sale_id | product_id | sale_date | quantity |
---|---|---|---|
6791 | 1111 | 01/18/2022 | 25 |
7805 | 2222 | 01/20/2022 | 45 |
5296 | 1111 | 01/28/2022 | 15 |
6592 | 3333 | 02/10/2022 | 30 |
4519 | 2222 | 02/20/2022 | 50 |
We want to output a table that shows the average quantity sold per month for each product.
month | product_id | avg_quantity |
---|---|---|
1 | 1111 | 20 |
1 | 2222 | 45 |
2 | 2222 | 50 |
2 | 3333 | 30 |
SELECT DATE_PART('month', sale_date) as month, product_id, AVG(quantity) OVER (PARTITION BY product_id, DATE_PART('month', sale_date)) as avg_quantity FROM sales ORDER BY month, product_id;
In this query, we are using the PostgreSQL DATE_PART
function to extract the month from the sale_date
. Then, we are using the AVG
window function to calculate the average quantity sold per month for each product using the PARTITION BY
clause to separate the data into partitions. Finally, the query is ordered by month
and product_id
.
To practice a related window function SQL problem on DataLemur's free interactive coding environment, try this Google SQL Interview Question:
Explore Fastenal's insights on the role of AI in supply chains and discover how this technology is enhancing efficiency and transforming logistics! Understanding Fastenal's innovative applications of AI can provide valuable perspectives on how businesses are optimizing their operations and staying competitive in a fast-paced market.
Assume you had a table of Fastenal employee salary data. Write a SQL query to find the 2nd highest salary among all employees.
employees
Example Input:employee_id | salary |
---|---|
1 | 2500 |
2 | 800 |
3 | 1000 |
4 | 1200 |
second_highest_salary |
---|
1200 |
Code your solution to this interview question and run your code right in DataLemur's online SQL environment:
SELECT MAX(salary) AS second_highest_salary FROM employee WHERE salary < ( SELECT MAX(salary) FROM employee );
You can find a detailed solution with hints here: 2nd Highest Salary.
COALESCE()
do?The COALESCE()
function is used to remove NULLs, and replace them with another value.
For example, say you were a Data Analyst at Fastenal and were doing a customer analytics project to see who the most marketing-engaged customers were, and had access to the below table.
fastenal_customers
:customer_id | email_engagement | sms_engagement |
---|---|---|
101 | very_active | not_opted_in |
201 | un-subscribed | NULL |
301 | NULL | not_opted_in |
401 | not_active | very_active |
501 | very_active | mildly_active |
303 | NULL | NULL |
Before you could procede, you had to remove the NULLs, and replace them with the default value (not_active for email, and not_opted_in for SMS). To do this, you'd run the following query:
SELECT customer_id, COALESCE(email_engagement, "not_active") as email_engagement, COALESCE(sms_engagement, "not_opted_in") as sms_engagement FROM fastenal_customers;
This would get you the following output:
customer_id | email_engagement | sms_engagement |
---|---|---|
101 | very_active | not_opted_in |
201 | un-subscribed | not_opted_in |
301 | not_active | not_opted_in |
401 | not_active | very_active |
501 | very_active | mildly_active |
303 | not_active | not_opted_in |
Fastenal, a company that sells various industrial and construction supplies, wants to better understand their inventory. Design two tables, one for their products and one for their inventory in various warehouses. Then, write a PostgreSQL query to determine which products are below the average stock level across all warehouses.
Here are the descriptions for both tables:
products
table should consist of the columns: product_id
, product_name
, category
and cost_per_unit
.inventory
table should consist of: warehouse_id
, product_id
, stock
and last_stock_date
.products
Example Input:product_id | product_name | category | cost_per_unit |
---|---|---|---|
101 | Bolt | Fasteners | 0.5 |
102 | Hammer | Tools | 20 |
103 | Drill | Tools | 150 |
104 | Nuts | Fasteners | 0.2 |
105 | Wrench | Tools | 25 |
inventory
Example Input:warehouse_id | product_id | stock | last_stock_date |
---|---|---|---|
2001 | 101 | 5000 | 2022-08-10 |
2001 | 102 | 100 | 2022-08-05 |
2002 | 103 | 50 | 2022-08-07 |
2002 | 104 | 7000 | 2022-08-10 |
2003 | 105 | 50 | 2022-08-09 |
In this task, the task is to identify the products which are below the average stock level across all the warehouses. This can be achieved by computing the average stock level from inventory
table and then, join it with the products
table to list those products. Here is the SQL query:
WITH avg_stock AS ( SELECT AVG(stock) AS average_stock FROM inventory ) SELECT p.product_id, p.product_name, p.category, i.stock FROM products p JOIN inventory i ON p.product_id = i.product_id WHERE i.stock < (SELECT average_stock FROM avg_stock) ORDER BY i.stock;
This query first calculates the average stock from the inventory
table and then selects the products from the products
table which have their stock level below average. The result is then ordered by the stock level of the products.
Joins in SQL allow you to combine data from different tables based on a shared key or set of keys.
Four JOIN types are available in SQL. For an example of each one, say you had sales data exported from Fastenal's Salesforce CRM stored in a PostgreSQL database, and had access to two tables: sales
and fastenal_customers
.
INNER JOIN
: retrieves rows from both tables where there is a match in the shared key or keys. For example, an INNER JOIN
between the Sales
table and the Customers
table would retrieve only the rows where the customer_id
in the Sales
table matches the customer_id
in the fastenal_customers
table.
LEFT JOIN
: retrieves all rows from the left table (in this case, the sales
table) and any matching rows from the right table (the fastenal_customers
table). If there is no match in the right table, NULL
values will be returned for the right table's columns.
RIGHT JOIN
: retrieves all rows from the right table (in this case, the customers
table) and any matching rows from the left table (the sales
table). If there is no match in the left table, NULL
values will be returned for the left table's columns.
FULL OUTER JOIN
: retrieves all rows from both tables, regardless of whether there is a match in the shared key or keys. If there is no match, NULL
values will be returned for the columns of the non-matching table.
Fastenal is a company that sells industrial and construction supplies through a B2B model. For their upcoming sales campaign, the marketing department wants to target customers who spent more than $500 in the last 3 months and are located in the 'Midwest' region. Using the orders
and customers
tables, write a SQL query to filter out the information.
orders
Example Input:order_id | customer_id | order_date | total_cost |
---|---|---|---|
9907 | 564 | 12/07/2021 | $250.00 |
1034 | 123 | 01/16/2022 | $120.00 |
2275 | 256 | 02/28/2022 | $600.00 |
3201 | 123 | 04/01/2022 | $200.50 |
3289 | 564 | 05/10/2022 | $350.00 |
customers
Example Input:customer_id | name | region |
---|---|---|
123 | ABC Corporation | Northeast |
256 | XYZ Industries | Midwest |
564 | 123 Enterprises | Midwest |
customer_id | name |
---|---|
256 | XYZ Industries |
SELECT c.customer_id, c.name FROM customers c JOIN ( SELECT o.customer_id, SUM(o.total_cost) OVER( PARTITION BY o.customer_id ORDER BY o.order_date RANGE BETWEEN INTERVAL '3 months' PRECEDING AND CURRENT ROW ) AS rolling_sum FROM orders o ) s ON c.customer_id = s.customer_id WHERE s.rolling_sum > 500 AND c.region = 'Midwest'
This query first creates a subquery s
to calculate the cumulative sum of total_cost
for each customer over a rolling window of the last 3 months. This subquery result is then joined with the customers
table on customer_id
. The WHERE
clause is used to filter out customers who meet the condition of having a rolling sum larger than $500 and are located in 'Midwest'.
A database index is a data structure that improves the speed of data retrieval operations on a database table.
There are few different types of indexes that can be used in a database:
For a concrete example, say you had a table of Fastenal customer payments with the following columns:
payment_id
customer_id
payment_amount
payment_date
Here's what a clustered index on the payment_date
column would look like:
CREATE CLUSTERED INDEX payment_date_index ON fastenal_customer_payments (payment_date)
A clustered index on the payment_date
column would determine the physical order of the records in the table based on the payment_date
. This means that the records with the earliest payment_date
values would be stored together physically in the table, followed by records with later payment_date values. This speeds up queries that filter or sort the data based on the payment_date
, as the records are already physically sorted in the table. For example, if you want to retrieve all the payments made in the month of June, the database can use the clustered index to quickly locate and retrieve the desired records without having to search through the entire table.
Fastenal is an industrial supply company that sells various products to customers. Customers, while registering with Fastenal, have to submit their name, contact, and business type. A customer is vetted (approved) when their business type is verified by the company. Not every customer's provided business type is vetted by the company.
Consider a database with a table customers
which holds the records of customers. The customers
table has the following columns:
customer_id
(integer): a unique identifier for each customer;name
(string): the name of the customer;contact
(string): the contact details of the customer;businesstype
(string): the business type of the customer;vetted
(boolean): a flag indicating if the business type of the customer has been vetted.Fastenal often targets vetted customers for their marketing needs. They have noticed that a considerable portion of their vetted customers have 'industrial' in their business type.
Your task is to write a SQL query to find the names and contact details of all vetted customers whose business type includes the string 'industrial'.
customers
Example Input:customer_id | name | contact | businesstype | vetted |
---|---|---|---|---|
1 | ABC Corporation | abc@corporation.com | Industrial Supply | true |
2 | XYZ Ltd | xyz@ltd.com | Industrial Manufacturing | true |
3 | RST Inc | rst@inc.com | Retail Industry | true |
4 | LMN LLC | lmn@llc.com | Industrial Construction | true |
5 | GHI Co | ghi@co.com | Agriculture | false |
name | contact |
---|---|
ABC Corporation | abc@corporation.com |
XYZ Ltd | xyz@ltd.com |
LMN LLC | lmn@llc.com |
Here is a PostgreSQL query that solves the problem:
SELECT name, contact FROM customers WHERE vetted = true AND businesstype LIKE '%industrial%';
This query filters records from the customers
table where the vetted
column is true
and the businesstype
string contains 'industrial'. The LIKE
keyword is used here with the %
wildcard character to match any sequence of characters. The %industrial%
pattern will match any business type that contains the word 'industrial' anywhere in the string. The query then selects the name
and contact
columns from these filtered records.
You are provided with two tables, customers
and orders
. The customers
table has columns customer_id
, first_name
, last_name
and email
. The orders
table has columns order_id
, customer_id
, product_id
, quantity
and order_date
.
Write an SQL query that joins these two tables on customer_id
and returns each customer's full name (first name plus last name) who purchased a certain product (let's say product_id = 105), ordered by the most recent order made.
customers
Example Input:customer_id | first_name | last_name | |
---|---|---|---|
101 | John | Doe | jdoe@email.com |
102 | Jane | Smith | jsmith@email.com |
103 | Jim | Brown | jbrown@email.com |
104 | Julia | Roberts | jroberts@email.com |
orders
Example Input:order_id | customer_id | product_id | quantity | order_date |
---|---|---|---|---|
5001 | 101 | 105 | 2 | 2022-07-10 |
5002 | 102 | 103 | 1 | 2022-07-15 |
5003 | 101 | 105 | 3 | 2022-07-18 |
5004 | 103 | 105 | 1 | 2022-07-20 |
SELECT CONCAT(c.first_name, ' ', c.last_name) AS full_name, o.order_date FROM customers AS c JOIN orders AS o ON c.customer_id = o.customer_id WHERE o.product_id = 105 ORDER BY o.order_date DESC;
In the above PostgreSQL query, we are joining the customers
table with the orders
table on the customer_id
field. We want to get the full_name
of customers who have ordered a specific product (with product_id = 105
), therefore we use a WHERE
clause to filter these records. CONCAT
function is used to concatenate first name and last name. We then order the result by the order_date
in descending order to find out the most recent orders first.
Because join questions come up so often during SQL interviews, try an interactive Spotify JOIN SQL question:
Assuming that you've already got basic SQL skills, the next best tip we have to prepare for the Fastenal SQL interview is to solve as many practice SQL interview questions as you can! Beyond just solving the above Fastenal SQL interview questions, you should also solve the 200+ DataLemur interview questions which come from companies like Meta, Google and industrial and electrical distribution companies like Fastenal.
Each problem on DataLemur has multiple hints, step-by-step solutions and best of all, there's an interactive SQL code editor so you can right online code up your query and have it checked.
To prep for the Fastenal SQL interview you can also be wise to solve SQL questions from other industrial and electrical distribution companies like:
However, if your SQL coding skills are weak, don't worry about going right into solving questions – refresh your SQL knowledge with this SQL tutorial for Data Analytics.
This tutorial covers topics including Union vs. UNION ALL and CASE/WHEN/ELSE statements – both of which show up frequently in SQL job interviews at Fastenal.
Besides SQL interview questions, the other question categories tested in the Fastenal Data Science Interview are:
To prepare for the Fastenal Data Science interview have a firm understanding of the company's values and company principles – this will be important for acing the behavioral interview. For the technical Data Science interviews, get ready by reading Ace the Data Science Interview. The book's got: