https://github.com/glitzzybetty/sql-personal-project
This is a show case of my SQL super powers in an assumed fictional company
https://github.com/glitzzybetty/sql-personal-project
business-analytics business-intelligence dataanalytics database mssql-database sql
Last synced: 11 months ago
JSON representation
This is a show case of my SQL super powers in an assumed fictional company
- Host: GitHub
- URL: https://github.com/glitzzybetty/sql-personal-project
- Owner: Glitzzybetty
- Created: 2024-06-17T08:20:56.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-07-11T00:21:57.000Z (over 1 year ago)
- Last Synced: 2025-01-18T13:56:22.366Z (about 1 year ago)
- Topics: business-analytics, business-intelligence, dataanalytics, database, mssql-database, sql
- Language: TSQL
- Homepage: https://glitzzybetty.github.io/SQL-Project/
- Size: 264 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
Case Study #1 - Analyze Data in a Model Car Database
Contents
- Introduction
- Project Scenerio
- Project Objective
- Database Information
- Case Study Questions & Solutions
- Bonus Questions & Solutions
- Key Insights
Introduction
As a data analyst at the fictional Mint Classics Company, am helping to analyze data in a relational database with the goal of supporting inventory-related business decisions that lead to the closure of a storage facility.
Project Scenerio
Mint Classics Company, a retailer of classic model cars and other vehicles, is looking at closing one of their storage facilities.
To support a data-based business decision, they are looking for suggestions and recommendations for reorganizing or reducing inventory, while still maintaining timely service to their customers. For example, they would like to be able to ship a product to a customer within 24 hours of the order being placed.
Project Objective
- 1. Explore products currently in inventory.
- 2. Determine important factors that may influence inventory reorganization/reduction.
- 3. Provide analytic insights and data-driven recommendations.
Database Information
The Database for this project was initially configured to MySQL pattern, I had to convert it to MSSQL pattern. Re-wrote the table creations, and the data insertions with the order datails containing more that 1000 rows. I used partly AI prompting as additional assistance for ideas. It was QED.
Mint Classic Entity Relationship Diagram (ERD)
Exploring to understand some Business Demographic Information
It is very important to find out out business demography, customer segments, doing some background checks before attemping to fix underlying problems.
Where are the top five customers aggregations located
- The SQL query retrieves the
customerNumbershows theircountryof residents and calculates the average (creditLimit) in each country group they belong to. - It presents data from the
customerstable.
- The results are grouped by top 5
country. - The query then calculates the average
creditlimitfor each group of customers with the samecountry. - Finally, the results are sorted in descending order based on the
customerNumberaggregation. - The findings here shows that there are more customers in the USA
Explain MintClassic Employees hierarchy, and their aggregation per location
- The SQL query retrieves the
JobTitleof Employees, shows the count ofEmployeeNumberin that position and the report to person, their jobtitle and theircountry. - It presents data from the
Employeestable, self joins to get report to person and joins withofficecodeto get thecountryi.e. location of these staffs.
- The results are grouped by top 5
jobTitlenamesandcountry. - The findings points out that majority of employees were from USA, pointing out the reasons more customers are the largest in US. Also, it was discovered one employee who is a sales rep reports to another sales rep in Japan, some questions needs to be asked the stakeholders, especially the VP sales.
```sql
-- Top 5 Countries of Mint Classic customers
select top 5
country,
count(customerNumber) as [Number of Customers],
round(avg(creditLimit),0) as [Average Credit Limit]
from [mintclassics].[dbo].[customers]
group by country
order by count(customerNumber) desc
```
Answer:
```sql
SELECT
e1.jobTitle,
COUNT(e1.employeeNumber) AS EmployeeCount,
COALESCE(
CONCAT(e2.firstName, ' ', e2.lastName),
'No one' -- This will show 'No one' for the President
) AS [Report to Person],
COALESCE(
e2.jobTitle,
'No one' -- This will show 'No one' for the President
) AS [Report To Person Job Title],
COALESCE(
o.[country],
'No one' -- This will show 'No one' for the President
) AS [Report To Person Country]
FROM
[mintclassics].[dbo].[employees] e1
LEFT JOIN
[mintclassics].[dbo].[employees] e2 ON e1.reportsTo = e2.employeeNumber
JOIN
[mintclassics].[dbo].[offices] o ON e2.officeCode = o.officeCode
GROUP BY
e1.jobTitle,
e2.jobTitle,
e2.firstName,
e2.lastName,
o.[country]
ORDER BY
EmployeeCount DESC;
```
Answer:
Advance Questions
Critical Question are being asked to reveal Business problems, so that solution can be readily presented
Are there products with high inventory but low sales? How can we optimize the inventory of these products?
- The SQL uses
CTE i.e. common Table Expression(product_sales):
- Calculates
totalQuantitySold,InventoryTurnOverRatio, andStockToSalesRatio. - Uses ISNULL and NULLIF to handle division by zero errors.
- Selects the top 10 products by
StockToSalesRatio. - Orders the results by
StockToSalesRatioin descending order to highlight products with high inventory relative to sales. - Inventory Turnover Ratio (ITR): Measures how often inventory is sold and replaced over a period. A higher ITR indicates better performance.
- Stock to Sales Ratio (SSR): Compares average inventory to sales. A higher SSR suggests overstocking and potential inefficiencies.
- This script identifies products with high inventory but low sales and provide a basis for optimization strategies like targeted promotions, inventory reduction, or restocking adjustments.
Are all the warehouses currently in use still necessary? How can we review warehouses with low or inactive inventory?
- The SQL uses
CTE i.e. common Table Expression(warehouse_inventory):
- Calculates
totalQuantityOrdered,InventoryTurnOverRatio, andStockToSalesRatio. - Selects
warehouseName,Number of Active Customers,totalInventory. - Orders the results by
StockToSalesRatioin descending order to highlight warehouses with high inventory relative to sales. - Highest SSR on the list implies a high amount of inventory relative to sales.
- Suggests overstocking, higher holding costs, and potential obsolescence.
- May indicate that inventory is not turning over quickly enough, leading to inefficiency.
- Highest ITR Indicates high inventory turnover.
- Offer incentives or discounts to move excess inventory.
- Slow down or temporarily halt new inventory orders until sales catch up with existing stock.
- Analyze the reasons for low sales, such as product relevance, competition, or market demand, and take corrective actions.
Is there a relationship between product prices and their sales levels? How can price adjustments impact sales?
- This query examines the relationship between product prices (MSRP) i.e. Manufacturer suggested Retail Price and sales volumes.
- By analyzing the output, the company can identify if higher prices correspond to lower sales and
- consider price adjustments to optimize sales volumes.
Who are the customers contributing the most to sales? How can we focus sales efforts on these valuable customers?
- This query identifies the top 10 customers by total sales.
- Focusing sales efforts on these valuable customers can involve personalized marketing strategies, loyalty programs, and enhanced customer service.
```sql
WITH product_sales AS (
SELECT
p.productCode,
p.productName,
p.quantityInStock,
ISNULL(SUM(od.quantityOrdered), 0) AS totalQuantitySold,
ISNULL(SUM(od.quantityOrdered * od.priceEach) / NULLIF(AVG(p.quantityInStock), 0), 1) AS InventoryTurnOverRatio,
ISNULL(AVG(p.quantityInStock) / NULLIF(SUM(od.quantityOrdered * od.priceEach), 0), 1) AS StockToSalesRatio
FROM
products p
LEFT JOIN
orderdetails od ON p.productCode = od.productCode
GROUP BY
p.productCode, p.productName, p.quantityInStock, p.MSRP
)
SELECT TOP 10
productCode,
productName,
quantityInStock,
totalQuantitySold,
InventoryTurnOverRatio,
CAST(ROUND(StockToSalesRatio, 2) AS float) AS StockToSalesRatio
FROM
product_sales
ORDER BY
StockToSalesRatio DESC;
```
Answer 1:
Main Query:
Comments on Key Metrics:
```sql
WITH warehouse_inventory AS (
SELECT
w.warehouseCode,
w.warehouseName,
COUNT(DISTINCT o.customerNumber) AS [Number of Active Customers],
SUM(p.quantityInStock) AS totalInventory,
ISNULL(SUM(od.quantityOrdered), 0) AS totalQuantityOrdered,
ISNULL(SUM(od.quantityOrdered * od.priceEach) / NULLIF(AVG(p.quantityInStock), 0), 1) AS InventoryTurnOverRatio,
ISNULL(AVG(p.quantityInStock) / NULLIF(SUM(od.quantityOrdered * od.priceEach), 0), 1) AS StockToSalesRatio
FROM
warehouses w
LEFT JOIN
products p ON w.warehouseCode = p.warehouseCode
LEFT JOIN orderdetails od ON p.productCode = od.productCode
LEFT JOIN orders o ON od.orderNumber = o.orderNumber
GROUP BY
w.warehouseCode, w.warehouseName--, p.quantityInStock, p.MSRP
)
SELECT
warehouseCode,
warehouseName,
[Number of Active Customers],
totalInventory,
totalQuantityOrdered,
round(cast(InventoryTurnOverRatio as float), 2) as InventoryTurnOverRatio,
round(cast(StockToSalesRatio as float),4) as StockToSalesRatio
FROM
warehouse_inventory
--WHERE
-- totalInventory < 50;
ORDER BY StockToSalesRatio DESC;
```
Answer 2:
Main Query:
Comments on Key Metrics:
Optimisation Strategy
To Increase ITR and reduce SSR:
```sql
SELECT Top 10
p.productCode,
p.productName,
p.MSRP, cast(round(Avg(od.priceEach), 2) as float) as avgPriceSold,
Avg(od.priceEach) - p.MSRP as [Price Diff],
SUM(od.quantityOrdered) AS totalQuantitySold
FROM
products p
JOIN
orderdetails od ON p.productCode = od.productCode
GROUP BY
p.productCode, p.productName, p.MSRP
ORDER BY
SUM(od.quantityOrdered) desc;
```
Answer 3:
```sql
SELECT TOP 10
c.customerNumber,
c.customerName,
c.[country],
SUM(od.quantityOrdered * p.MSRP) AS totalSales
FROM
customers c
JOIN
orders o ON c.customerNumber = o.customerNumber
JOIN
orderdetails od ON o.orderNumber = od.orderNumber
JOIN
products p ON od.productCode = p.productCode
GROUP BY
c.customerNumber, c.customerName, c.[country]
ORDER BY
totalSales DESC
```