Skip to content
SQL Server Example - Bicycle Sales Database
  • AI Chat
  • Code
  • Report
  • Bicycle Sales Database

    This workspace is automatically connected to a Microsoft SQL Server database containing two schemas (sales and production), which in turn have various details about the sales and inventory for bike stores (source). I will use this workspace to demonstrate my ability to use SQL. The workspace will be broken up into two parts 1) general exploration and 2) ad hoc reporting simulation.

    The first section I will use SQL just to explore the data and pull general numbers and stats from the data. The second part I will have a specific question that a stakeholder may ask, and will provide a query to answer the question.

    The Schema layout is shown below

    Data Exploration

    Looking at the states the stores are located in and the number of orders and total quantity of each state.

    Unknown integration
    DataFrameavailable as
    df
    variable
    SELECT s.state
            ,COUNT(DISTINCT s.store_id) AS Stores
            ,COUNT(DISTINCT o.order_id) AS Orders
            ,SUM(i.quantity) AS Quantity
        FROM Sales.stores AS s
        LEFT JOIN Sales.orders AS o
            ON o.store_id = s.store_id
        LEFT JOIN Sales.order_items AS i
            ON i.order_id = o.order_id
        GROUP BY s.state
    Unknown integration
    DataFrameavailable as
    df
    variable
    SELECT b.brand_name
            ,SUM(s.quantity) AS TotalStock
            ,SUM(s.quantity * list_price) AS StockValue
        FROM Production.brands AS b
        LEFT JOIN Production.products AS p
            ON p.brand_id = b.brand_id
        LEFT JOIN Production.stocks AS s
            ON s.product_id = p.product_id
        GROUP BY b.brand_name

    Ad Hoc Simulation

    In this section, I will post a simulated request from a stakeholder, followed by a SQL query to answer that question.

    Top Customers

    "We're looking at sending out a discount to our top customers as a 'Thank you', and would like to tailor it to them, can you get me a list of our top 10 customers by sales and the brand they use the most?"

    Unknown integration
    DataFrameavailable as
    df
    variable
    --Getting the top 10 customers by sales
    SELECT TOP 10 c.customer_id
            ,SUM(i.quantity * i.list_price) AS TotalSales
            ,ROW_NUMBER() OVER (ORDER BY SUM(i.quantity * i.list_price) DESC) AS CustRank
        INTO #TopCust
        FROM Sales.customers AS c
        LEFT JOIN Sales.orders AS o
            ON o.customer_id = c.customer_id
        LEFT JOIN Sales.order_items AS i
            ON i.order_id = o.order_id
        GROUP BY c.customer_id
        ORDER BY TotalSales DESC
    
    --Getting the Brands they buy
    SELECT t.CustRank
            ,c.customer_id
            ,CONCAT(c.first_name, ' ', c.last_name) AS CustomerName
            ,c.email
            ,b.brand_name
            ,SUM(i.quantity * i.list_price) AS TotalSales
        FROM Sales.customers AS c
        INNER JOIN #TopCust AS t
            ON t.customer_id = c.customer_id
        LEFT JOIN Sales.orders AS o
            ON o.customer_id = c.customer_id
        LEFT JOIN Sales.order_items AS i
            ON i.order_id = o.order_id
        LEFT JOIN Production.products AS p
            ON p.product_id = i.product_id
        LEFT JOIN Production.brands AS b
            ON b.brand_id = p.brand_id
        GROUP BY t.CustRank
            ,c.customer_id
            ,CONCAT(c.first_name, ' ', c.last_name)
            ,c.email
            ,b.brand_name
        ORDER BY CustRank ASC, TotalSales DESC 
            
    DROP TABLE #TopCust 
    
    --The resulting table shows the top 10 customers and the brands they buy ordered by total sales

    Sufficient Inventory

    "We want to make sure our stores are stocked with at least 3 months supply. Please get us a list for each store of their current inventory, the inventory they should have and the difference as a number and percentage, the current monetary value of the stock and estimated cost to reach the needed inventory. Please include brands and product names."

    (For this example I will use list_price as both list_price and purchase_price)

    Unknown integration
    DataFrameavailable as
    df
    variable
    --Necessary stock
    
    SELECT e.store_id
            ,e.product_id
            ,CEILING(AVG(e.monthly_qty)) AS avg_monthly_qty
            ,CEILING(AVG(e.monthly_qty)) * 3 AS three_month_qty
        INTO #Three_Month_Supply
        FROM (
            --Getting the qty of each product sold in each month in each store
            SELECT s.store_id
                    ,DATEADD(DAY, -(DAY(order_date) - 1), order_date) AS order_month
                    ,i.product_id
                    ,SUM(i.quantity) AS monthly_qty
                FROM Sales.stores AS s
                LEFT JOIN Sales.orders AS o
                    ON o.store_id = s.store_id
                LEFT JOIN Sales.order_items AS i
                    ON i.order_id = o.order_id
                GROUP BY s.store_id
                        ,i.product_id
                        ,DATEADD(DAY, -(DAY(order_date) - 1), order_date)
            ) AS e
        GROUP BY e.store_id
                ,e.product_id
    
    --Current and Needed Stock
    
    SELECT s.store_id
            ,t.product_id
            ,p.product_name
            ,b.brand_name
            ,t.quantity
            ,m.three_month_qty
            ,CASE WHEN m.three_month_qty - t.quantity > 0 THEN m.three_month_qty - t.quantity
                ELSE 0 END AS stock_needed
            ,t.quantity * p.list_price AS current_value
            ,(CASE WHEN m.three_month_qty - t.quantity > 0 THEN m.three_month_qty - t.quantity ELSE 0 END) * p.list_price AS supply_cost
        FROM Sales.stores AS s
        LEFT JOIN Production.stocks AS t
            ON t.store_id = s.store_id
        LEFT JOIN #Three_Month_Supply AS m
            ON m.store_id = s.store_id
                AND m.product_id = t.product_id
        LEFT JOIN Production.products AS p
            ON p.product_id = t.product_id
        LEFT JOIN Production.brands AS b
            ON b.brand_id = p.brand_id
        ORDER BY store_id
                ,product_id
    
    DROP TABLE #Three_Month_Supply

    Past Sales

    "I will need a report showing sales of each product by a specific brand for each store in a selected month and the preceeding 6 months. I will need this report for one specific brand at a time"

    Unknown integration
    DataFrameavailable as
    df
    variable
    --Setting variable
    DECLARE @brand VARCHAR(10);
    DECLARE @date DATE; --First day of the month
    SET @brand = 'Trek'
    SET @date = '2017-11-01'
    
    SELECT s.store_id
            ,s.store_name
            ,b.brand_name
            ,p.product_id
            ,p.product_name
            ,SUM(CASE WHEN DATEADD(DAY, -(DAY(order_date) - 1), order_date) = DATEADD(MONTH, -6, @date) THEN i.quantity * i.list_price ELSE 0 END) AS 'Six Months Previous'
            ,SUM(CASE WHEN DATEADD(DAY, -(DAY(order_date) - 1), order_date) = DATEADD(MONTH, -5, @date) THEN i.quantity * i.list_price ELSE 0 END) AS 'Five Months Previous'
            ,SUM(CASE WHEN DATEADD(DAY, -(DAY(order_date) - 1), order_date) = DATEADD(MONTH, -4, @date) THEN i.quantity * i.list_price ELSE 0 END) AS 'Four Months Previous'
            ,SUM(CASE WHEN DATEADD(DAY, -(DAY(order_date) - 1), order_date) = DATEADD(MONTH, -3, @date) THEN i.quantity * i.list_price ELSE 0 END) AS 'Three Months Previous'
            ,SUM(CASE WHEN DATEADD(DAY, -(DAY(order_date) - 1), order_date) = DATEADD(MONTH, -2, @date) THEN i.quantity * i.list_price ELSE 0 END) AS 'Two Months Previous'
            ,SUM(CASE WHEN DATEADD(DAY, -(DAY(order_date) - 1), order_date) = DATEADD(MONTH, -1, @date) THEN i.quantity * i.list_price ELSE 0 END) AS 'Previous Month'
            ,SUM(CASE WHEN DATEADD(DAY, -(DAY(order_date) - 1), order_date) = @date THEN i.quantity * i.list_price ELSE 0 END) AS 'Selected Month'
        FROM Sales.stores AS s
        LEFT JOIN Sales.orders AS o
            ON o.store_id = s.store_id
        LEFT JOIN Sales.order_items AS i
            ON i.order_id = o.order_id
        LEFT JOIN Production.products AS p
            ON p.product_id = i.product_id
        LEFT JOIN Production.brands AS b
            ON b.brand_id = p.brand_id
        WHERE b.brand_name = @brand
            AND o.order_date >= DATEADD(MONTH, -6, @date)
            AND o.order_date < DATEADD(MONTH, 1, @date)
        GROUP BY s.store_id
            ,s.store_name
            ,b.brand_name
            ,p.product_id
            ,p.product_name
        ORDER BY store_id
            ,product_id