Northwind Traders Database Exploration

About Northwind Traders

Northwind Traders is a fictional company that buys products and resells them to customers.

As an incentive, the company decided to give a bonus to high performing employees. These high performing employees being the ones who are responsible for the five highest order amounts. This analysis will focus on correctly identifying the employees that are eligible for this bonus.

Database Diagram

To get the highest order amounts and the employees who completed them, these following tables will be needed: Employees, Orders, Order_Details and Products. Using SSMS, I have created a diagram showing the tables that will be used for this analysis.

Setting up SQL connection with Rstudio

For this analysis, I used RStudio to connect to my SQLite server. Following R packages were used to create this connection: DBI, odbc, RSQLite. I have downloaded the Northwind Traders database creation sql file from this repository.

con <- odbc::dbConnect(odbc::odbc(), Driver = "SQLite3 ODBC Driver", 
                       Server = "localhost\\SQLITE3", 
                       Database = "Northwind.db", 
                       Trusted_Connection = "True")

Analysis

After examining these tables one by one, the following plan is made. FirstName and LastName columns from the Employees table are needed to have the names of the employees. Then, Employees and Orders tables can be joined using their common column which is EmployeeID. This join is important to be able to connect the EmployeeID to OrderID to figure out which employee is responsible for which order.

SELECT LastName, FirstName, OrderID
FROM Employees
INNER JOIN Orders
ON Employees.EmployeeID = Orders.EmployeeID
ORDER BY LastName, FirstName
Displaying records 1 - 10
LastName FirstName OrderID
Buchanan Steven 10248
Buchanan Steven 10254
Buchanan Steven 10269
Buchanan Steven 10297
Buchanan Steven 10320
Buchanan Steven 10333
Buchanan Steven 10358
Buchanan Steven 10359
Buchanan Steven 10372
Buchanan Steven 10378

Using OrderID column Orders and Order_Details tables can be joined, which would help in knowing the quantity of the order.

SELECT LastName, FirstName, Orders.OrderID, Quantity
FROM Employees
INNER JOIN Orders
ON Employees.EmployeeID = Orders.EmployeeID
INNER JOIN Order_Details
ON Orders.OrderID = Order_Details.OrderID
ORDER BY LastName, FirstName
Displaying records 1 - 10
LastName FirstName OrderID Quantity
Buchanan Steven 10248 12
Buchanan Steven 10248 10
Buchanan Steven 10248 5
Buchanan Steven 10254 15
Buchanan Steven 10254 21
Buchanan Steven 10254 21
Buchanan Steven 10269 60
Buchanan Steven 10269 20
Buchanan Steven 10297 60
Buchanan Steven 10297 20

Finally, joining Products table with Order_Details table via ProductID column is necessary to check the price of the product, which will help in finding the highest order amounts.

SELECT LastName, FirstName, Orders.OrderID, Products.ProductID, Quantity, 
Products.UnitPrice
FROM Employees
INNER JOIN Orders
ON Employees.EmployeeID = Orders.EmployeeID
INNER JOIN Order_Details
ON Orders.OrderID = Order_Details.OrderID
INNER JOIN Products
ON Order_Details.ProductID = Products.ProductID
ORDER BY LastName, FirstName
Displaying records 1 - 10
LastName FirstName OrderID ProductID Quantity UnitPrice
Buchanan Steven 10248 11 12 21
Buchanan Steven 10248 42 10 14
Buchanan Steven 10248 72 5 34.8
Buchanan Steven 10254 24 15 4.5
Buchanan Steven 10254 55 21 24
Buchanan Steven 10254 74 21 10
Buchanan Steven 10269 33 60 2.5
Buchanan Steven 10269 72 20 34.8
Buchanan Steven 10297 39 60 18
Buchanan Steven 10297 72 20 34.8

To get to the highest sale amount the total cost of each order is needed, which can be easily calculated by first multiplying the Quantity column from the Order_Details table with the UnitPrice column from the Products table and then summing the results per order.

SELECT LastName, FirstName, Orders.OrderID, Products.ProductID, 
sum(Quantity*Products.UnitPrice) AS SalesAmount
FROM Employees
INNER JOIN Orders
ON Employees.EmployeeID = Orders.EmployeeID
INNER JOIN Order_Details
ON Orders.OrderID = Order_Details.OrderID
INNER JOIN Products
ON Order_Details.ProductID = Products.ProductID
GROUP BY Orders.OrderID
Displaying records 1 - 10
LastName FirstName OrderID ProductID SalesAmount
Buchanan Steven 10248 72 566.00
Suyama Michael 10249 51 2329.25
Peacock Margaret 10250 65 2267.25
Leverling Janet 10251 65 839.50
Peacock Margaret 10252 60 4662.50
Leverling Janet 10253 49 1806.00
Buchanan Steven 10254 74 781.50
Dodsworth Anne 10255 59 3115.75
Leverling Janet 10256 77 648.00
Peacock Margaret 10257 77 1400.50

With this last code, the business question is ready to be answered. The only thing left to do is sort this final table’s SalesAmount column in a descending order which can be done by a simple ORDER BY clause. While at it, since only top five highest sales amount is needed, table length can also be limited by 5.

SELECT LastName, FirstName, Orders.OrderID, Products.ProductID, 
sum(Quantity*Products.UnitPrice) AS SalesAmount
FROM Employees
INNER JOIN Orders
ON Employees.EmployeeID = Orders.EmployeeID
INNER JOIN Order_Details
ON Orders.OrderID = Order_Details.OrderID
INNER JOIN Products
ON Order_Details.ProductID = Products.ProductID
GROUP BY Orders.OrderID
ORDER BY SalesAmount DESC
LIMIT 5
5 records
LastName FirstName OrderID ProductID SalesAmount
Fuller Andrew 10865 39 17250.0
King Robert 11030 59 16321.9
Davolio Nancy 10981 38 15810.0
Buchanan Steven 10372 72 15353.6
King Robert 10424 68 14366.5

Results are intriguing. Yes, this table shows exactly five of the highest sales amount, however they belong to these four employees only: Awdrew Fuller, Robert King, Nancy Davolio and Steven Buchanan. Since the business question is ambiguous about whether the bonus goes to the five highest sales regardless of the employee count or it goes to the five highest sales by five different employees, it would be ideal to prepare an additional table with the latter scenario in mind.

SELECT LastName, FirstName, Orders.OrderID, Products.ProductID, 
sum(Quantity*Products.UnitPrice) AS SalesAmount
FROM Employees
INNER JOIN Orders
ON Employees.EmployeeID = Orders.EmployeeID
INNER JOIN Order_Details
ON Orders.OrderID = Order_Details.OrderID
INNER JOIN Products
ON Order_Details.ProductID = Products.ProductID
GROUP BY Orders.OrderID
HAVING Orders.OrderID IN (10865, 11030, 10981, 10372, 10417)
ORDER BY SalesAmount DESC
LIMIT 5
5 records
LastName FirstName OrderID ProductID SalesAmount
Fuller Andrew 10865 39 17250.0
King Robert 11030 59 16321.9
Davolio Nancy 10981 38 15810.0
Buchanan Steven 10372 72 15353.6
Peacock Margaret 10417 77 14104.0

Results

After further simplifying these two final tables, both are ready to be reported to the sales manager.

SELECT LastName, FirstName, sum(Quantity*Products.UnitPrice) AS SalesAmount
FROM Employees
INNER JOIN Orders
ON Employees.EmployeeID = Orders.EmployeeID
INNER JOIN Order_Details
ON Orders.OrderID = Order_Details.OrderID
INNER JOIN Products
ON Order_Details.ProductID = Products.ProductID
GROUP BY Orders.OrderID
ORDER BY SalesAmount DESC
LIMIT 5
5 records
LastName FirstName SalesAmount
Fuller Andrew 17250.0
King Robert 16321.9
Davolio Nancy 15810.0
Buchanan Steven 15353.6
King Robert 14366.5

According to the table on top, these four employees are eligible for the bonus:
1. Andrew Fuller
2. Robert King
3. Nancy Davolio
4. Steven Buchanan

According to the table on the bottom, these five employees are eligible for the bonus:
1. Andrew Fuller
2. Robert King
3. Nancy Davolio
4. Steven Buchanan
5. Margaret Peacock

SELECT LastName, FirstName, sum(Quantity*Products.UnitPrice) AS SalesAmount
FROM Employees
INNER JOIN Orders
ON Employees.EmployeeID = Orders.EmployeeID
INNER JOIN Order_Details
ON Orders.OrderID = Order_Details.OrderID
INNER JOIN Products
ON Order_Details.ProductID = Products.ProductID
GROUP BY Orders.OrderID
HAVING Orders.OrderID IN (10865, 11030, 10981, 10372, 10417)
ORDER BY SalesAmount DESC
LIMIT 5
5 records
LastName FirstName SalesAmount
Fuller Andrew 17250.0
King Robert 16321.9
Davolio Nancy 15810.0
Buchanan Steven 15353.6
Peacock Margaret 14104.0