Dorcas Olawole

Junior Analyst

Junior data analyst working across Power BI, SQL, and Excel to surface revenue discrepancies and data quality issues

Scores reflect independent, automated grading of simulated business tasks completed on DataSimHQ.

Graded projects
7
Average best score
94/100
Career level
Junior Analyst
Core tool stack
Power BI (4) · SQL (2) · Excel (1)

About

Working through retail finance scenarios on a graded simulation platform, I have built Power BI data models from live PostgreSQL connections, written SQL aggregations to profile order data, and produced structured Excel audits complete with live PivotTable formulas and reconciliation flags. Each task required me to make deliberate choices about data types, schema targets, and calculation logic before producing any output.

The projects cluster around a single recurring business question: where does reported revenue diverge from raw transaction data, and why? That focus has pushed me to think carefully about kobo-to-naira conversions, duplicate customer flags, status-level exclusions, and baseline summary metrics before touching any visual layer.

Skills

SQL

  • SQL GROUP BY with COUNT and alias naming
  • SQL aggregate functions: MIN, MAX, SUM, ROUND
  • Cents-to-naira conversion in SQL and Power Query
  • ORDER BY for stakeholder-readable query output

Excel

  • PivotTable construction in Excel
  • GETPIVOTDATA formula for structured revenue splits
  • Structured table references with Order[[#Totals],[...]] syntax
  • Revenue reconciliation flagging in Excel

Power BI and Power Query

  • PostgreSQL connection via Power Query M code
  • Import mode table loading in Power BI
  • Power Query column arithmetic and renaming
  • Data type assignment for monetary columns in Power Query

Retail · Excel

Data audit identifying a revenue reconciliation gap for a retail finance team

Independent grading: 92/100(verify, opens in a new tab)

Problem

Nura Ibrahim at Meridian Retail (simulated retailer) provided a flat Excel file and asked for a structured audit of its contents before any formal analysis. The deliverable was a Data Audit sheet documenting at least three data quality issues and summarising key figures.

What I did

A PivotTable was built to capture all seven order statuses with their counts and revenue totals in a single view. Rather than hardcoding any figures, I used GETPIVOTDATA formulas to pull each status's revenue into an Include in Finance or Exclude in Finance column, making the split explicit and updatable. The revenue composition section used structured table references with Order[[#Totals],[...]] syntax to decompose total naira into subtotal, discount, shipping, and VAT components and verify they reconcile to gross revenue. A reconciliation flag in row 19 then surfaced the gap between the calculated net revenue and the NGN 38,500,000 figure reported by finance.

Finding

The audit surfaced a gap of approximately NGN 49,618 between the data-derived net revenue and the finance-reported figure, alongside NGN 18,426,410.13 in gross revenue tied to statuses that should be excluded from financial reporting.

Outcome

Nura had a live, formula-driven audit sheet that separated financeable from non-financeable revenue and flagged the specific reconciliation variance for follow-up, without any hardcoded values that could go stale.

Next step

Tracing the NGN 49,618 gap further would require checking whether any cancelled or returned orders were partially refunded and still counted in the net total, rather than treated as full exclusions.

  • PivotTable construction in Excel
  • GETPIVOTDATA formula for structured revenue splits
  • Structured table references with Order[[#Totals],[...]] syntax
  • Revenue reconciliation flagging in Excel

Retail · Power BI

Connecting Power BI to a live retail database across eight schema tables

Independent grading: 100/100(verify, opens in a new tab)

Problem

Nura Ibrahim, the CFO of Meridian Retail (simulated retailer), flagged a revenue discrepancy and needed a Power BI model built before any visual analysis could begin. The task was to connect Power BI Desktop to the Meridian PostgreSQL database and load eight specific tables from the retail schema using Import mode.

What I did

For each of the eight tables, I wrote M code targeting the retail schema explicitly on the Neon-hosted PostgreSQL endpoint, ensuring the correct schema was isolated rather than pulling from the full database. Import mode was chosen as specified, which pulls a snapshot into the model and makes subsequent DAX calculations faster. The tables spanned different grain levels, from line-level fact data in order_items to reference data in categories and stores, so having all eight present was necessary before any joins or measures could be reliable.

Finding

All eight tables loaded correctly, and Power BI auto-detected nine relationships across the model, including the order_items to orders to customers chain needed for revenue analysis.

Outcome

Nura had a complete, relationship-aware data model ready for visual development, with every column needed for revenue, customer, and inventory analysis present in Import mode.

let
 Source = PostgreSQL.Database("ep-frosty-glade-ab4k8hyw-pooler.eu-west-2.aws.neon.tech", "meridian_retail"),
 retail_categories = Source{[Schema="retail",Item="categories"]}[Data]
in
 retail_categories

This M code targets the retail schema by name, ensuring only the correct table is loaded rather than relying on default database browsing.

Next step

A useful next step would be to check whether the auto-detected relationships all point in the correct filter direction, particularly between orders and customers, before building any cross-table measures.

  • PostgreSQL connection via Power Query M code
  • Import mode table loading in Power BI
  • Data type assignment for monetary columns in Power Query

Retail · SQL

Profiling order status distribution to support a CFO revenue investigation

Independent grading: 97/100(verify, opens in a new tab)

Problem

Nura Ibrahim at Meridian Retail (simulated retailer) opened a revenue discrepancy investigation and needed an immediate picture of the orders table before any filtering began. The specific question was: what distinct order statuses exist, and how many orders carry each one?

What I did

I used GROUP BY status combined with COUNT(*) to enumerate every distinct value in the status column without assuming what those values would be. Sorting by the alias number_of_orders descending puts the most common statuses at the top, which makes the output readable without any further manipulation. A descriptive alias was applied rather than leaving the count column unnamed, so the result could be handed directly to a stakeholder.

Finding

Seven distinct statuses exist in the orders table: delivered, shipped, cancelled, confirmed, returned, pending, and refunded, with delivered the most frequent at 14,061 orders.

Outcome

Nura received a complete, sorted status enumeration that established which order types would need to be included or excluded before any revenue total could be considered reliable.

SELECT status, 
COUNT(*) AS number_of_orders
From retail.orders
GROUP BY status
ORDER BY number_of_orders DESC;

The ORDER BY on the alias surfaces the dominant status first, making the result immediately usable as a stakeholder-facing summary without reformatting.

Next step

The natural follow-on is to calculate the revenue contribution of each status separately, so cancelled and returned orders can be quantified as a share of gross revenue rather than just a count.

  • SQL GROUP BY with COUNT and alias naming
  • ORDER BY for stakeholder-readable query output

Retail · SQL

Establishing baseline revenue and date range metrics from the orders table

Independent grading: 95/100(verify, opens in a new tab)

Problem

Nura Ibrahim at Meridian Retail (simulated retailer) needed a single baseline summary of the orders table before any filtering or segmentation began. The required metrics were total order count, the earliest and latest order dates, and total revenue converted from kobo to naira.

What I did

COUNT(*) gave the total order count, and MIN and MAX on created_at captured the full date window without requiring any date formatting in advance. Revenue required dividing the cent-denominated total by 100.0 rather than the integer 100, which preserves the decimal portion and prevents integer truncation. ROUND with two decimal places was applied to produce a clean naira figure suitable for a finance audience.

Finding

The orders table contains 23,572 orders spanning 2021-01-12 through 2024-12-31, with total gross revenue of NGN 2,305,853,142.45.

Outcome

Nura had a confirmed baseline against which any filtered or segmented revenue figure could be benchmarked, establishing the full data window and gross total before any exclusions were applied.

SELECT 
COUNT(*) AS total_orders,
MIN(created_at) AS earliest_order,
MAX(created_at) AS latest_order, ROUND(SUM(total_cents) / 100.0, 2) AS total_revenue_naira
FROM retail.orders;

Dividing by 100.0 rather than the integer 100 ensures PostgreSQL performs decimal division, preserving kobo precision in the naira total.

Next step

Adding a ::date cast to the MIN and MAX columns would strip the timestamp from the output, which would make the date values cleaner when this query feeds a stakeholder report.

  • SQL aggregate functions: MIN, MAX, SUM, ROUND
  • Cents-to-naira conversion in SQL and Power Query
  • SQL GROUP BY with COUNT and alias naming

Retail · Power BI

Converting kobo price columns to naira in Power Query for downstream revenue calculations

Independent grading: 95/100(verify, opens in a new tab)

Problem

Nura Ibrahim at Meridian Retail (simulated retailer) identified that the order_items table stored all price columns in kobo, making them unusable directly in revenue and margin calculations. The task was to convert unit_price_cents, discount_cents, and line_total_cents to naira inside Power Query and rename them for clarity.

What I did

Each of the three cent-denominated columns was divided by 100 within the M code transformation steps and renamed to Unit Price (NGN), Discount (NGN), and Line Total (NGN). All three were cast as type number, the decimal type in Power Query, which is required for monetary columns that will feed downstream arithmetic. The same pattern had already been applied to the orders table in a prior step, so keeping the approach consistent meant any measure or visual built later could treat both tables the same way.

Finding

All three price columns were correctly converted to naira decimal values and renamed, with data types confirmed as number throughout.

Outcome

Nura's model now has clean, naira-denominated line-level price columns ready for any revenue or margin measure, without the risk of an analyst dividing by 100 again at the DAX layer.

Next step

Checking whether line_total_cents actually equals unit_price_cents minus discount_cents at the row level would confirm the column is calculated correctly in the source, or surface any rows where the arithmetic does not hold.

  • Power Query column arithmetic and renaming
  • Data type assignment for monetary columns in Power Query
  • Cents-to-naira conversion in SQL and Power Query
  • PostgreSQL connection via Power Query M code