A SQL Server Data Warehouse built using the Medallion Architecture (Bronze β Silver β Gold), integrating data from CRM and ERP source systems into a clean, business-ready Star Schema for analytics and reporting.
- Project Overview
- Architecture
- Star Schema (Gold Layer)
- Project Structure
- Data Sources
- ETL Pipeline
- Setup & Installation
- Usage
- Quality Checks
- Naming Conventions
- Technologies Used
- License
This project demonstrates a complete end-to-end data warehouse solution that:
- Ingests raw CSV data from two source systems (CRM & ERP) into a Bronze layer
- Cleanses & transforms the data in a Silver layer (deduplication, standardization, validation)
- Models the data into a Star Schema in the Gold layer for analytical consumption
| Layer | Purpose | Objects | Pattern |
|---|---|---|---|
| π₯ Bronze | Land raw data exactly as-is from CSV | 6 tables | BULK INSERT β tables |
| π₯ Silver | Cleanse, standardize, deduplicate | 6 tables | INSERT INTO β¦ SELECT with transforms |
| π₯ Gold | Business-ready star schema | 3 views | CREATE VIEW joining silver tables |
ββββββββββββββββ
β CSV Files β
β (CRM & ERP) β
ββββββββ¬ββββββββ
β BULK INSERT
βΌ
ββββββββββββββββββ
β π₯ BRONZE β
β (Raw Landing) β
β 6 tables β
ββββββββββ¬ββββββββ
β Cleanse & Transform
βΌ
ββββββββββββββββββ
β π₯ SILVER β
β (Cleansed) β
β 6 tables β
ββββββββββ¬ββββββββ
β Star Schema Views
βΌ
ββββββββββββββββββ
β π₯ GOLD β
β (Business) β
β 3 views β
ββββββββββ¬ββββββββ
β
βΌ
ββββββββββββββββββ
β π Analytics β
β & Reporting β
ββββββββββββββββββ
The Gold layer exposes three views forming a classic Star Schema design:
ββββββββββββββββββββ
β dim_customers β
ββββββββββββββββββββ
β customer_key (PK)β
β customer_id β
β customer_number β
β first_name β
β last_name β
β country β
β marital_status β
β gender β
β birthdate β
β create_date β
ββββββββββ¬ββββββββββ
β
β customer_key
βΌ
βββββββββββββββββββββββ
β fact_sales β
βββββββββββββββββββββββ
β order_number β
β product_key (FK) βββββββββ
β customer_key (FK) β β
β order_date β β
β shipping_date β β
β due_date β β
β sales_amount β β
β quantity β β
β price β β
βββββββββββββββββββββββ β
β product_key
βββββββββββ΄βββββββββββ
β dim_products β
ββββββββββββββββββββββ
β product_key (PK) β
β product_id β
β product_number β
β product_name β
β category_id β
β category β
β subcategory β
β maintenance β
β cost β
β product_line β
β start_date β
ββββββββββββββββββββββ
SQL_Data_Warehouse_Project/
β
βββ datasets/
β βββ source_crm/ # CRM source CSV files
β β βββ cust_info.csv
β β βββ prd_info.csv
β β βββ sales_details.csv
β βββ source_erp/ # ERP source CSV files
β βββ CUST_AZ12.csv
β βββ LOC_A101.csv
β βββ PX_CAT_G1V2.csv
β
βββ docs/
β βββ data_catalog.md # Gold layer column descriptions
β βββ naming_conventions.md # Project naming standards
β βββ data_architecture.png # Architecture diagram
β βββ data_flow.png # Data flow diagram
β βββ data_integration.png # Integration diagram
β βββ data_model.png # Star schema diagram
β βββ ETL.png # ETL process diagram
β
βββ scripts/
β βββ init_database.sql # Step 1: Create DB & schemas
β βββ bronze/
β β βββ ddl_bronze.sql # Step 2: Create bronze tables
β β βββ proc_load_bronze.sql # Step 3: Bronze load procedure
β βββ silver/
β β βββ ddl_silver.sql # Step 5: Create silver tables
β β βββ proc_load_silver.sql # Step 6: Silver load procedure
β βββ gold/
β βββ ddl_gold.sql # Step 8: Create gold views
β
βββ tests/
β βββ quality_checks_silver.sql # Silver layer data validation
β βββ quality_checks_gold.sql # Gold layer data validation
β
βββ .gitignore
βββ README.md
| File | Description | Key Columns |
|---|---|---|
cust_info.csv |
Customer master data | cst_id, cst_key, cst_firstname, cst_lastname, cst_gndr, cst_marital_status |
prd_info.csv |
Product catalog | prd_id, prd_key, prd_nm, prd_cost, prd_line |
sales_details.csv |
Sales transactions | sls_ord_num, sls_prd_key, sls_cust_id, sls_sales, sls_quantity, sls_price |
| File | Description | Key Columns |
|---|---|---|
CUST_AZ12.csv |
Customer demographics | cid, bdate, gen |
LOC_A101.csv |
Customer locations | cid, cntry |
PX_CAT_G1V2.csv |
Product categories | id, cat, subcat, maintenance |
- Full refresh pattern:
TRUNCATE+BULK INSERTfor each table - No transformations β data is landed exactly as-is from CSV
- 6 tables:
bronze.crm_cust_info,bronze.crm_prd_info,bronze.crm_sales_details,bronze.erp_cust_az12,bronze.erp_loc_a101,bronze.erp_px_cat_g1v2
| Table | Key Transformations |
|---|---|
crm_cust_info |
Deduplication via ROW_NUMBER(), gender/marital status standardization, TRIM() on names |
crm_prd_info |
Composite key splitting (prd_key β cat_id + prd_key), product line mapping, LEAD() for end dates |
crm_sales_details |
INT β DATE conversion with validation, sales recalculation (qty Γ price), price derivation |
erp_cust_az12 |
NAS prefix stripping from cid, future birthdate β NULL, gender standardization |
erp_loc_a101 |
Dash removal from cid, country name normalization (DE β Germany, US/USA β United States) |
erp_px_cat_g1v2 |
Direct copy (no transformation needed) |
dim_customers: Joins CRM customer info + ERP demographics + ERP locations, with CRM-priority gender resolutiondim_products: Joins CRM products + ERP categories, filtered to current products only (prd_end_dt IS NULL)fact_sales: Links sales transactions to dimension surrogate keys
| From Table | Join Column | β | To Table | Join Column |
|---|---|---|---|---|
silver.crm_cust_info |
cst_key |
β | silver.erp_cust_az12 |
cid |
silver.crm_cust_info |
cst_key |
β | silver.erp_loc_a101 |
cid |
silver.crm_prd_info |
cat_id |
β | silver.erp_px_cat_g1v2 |
id |
silver.crm_sales_details |
sls_prd_key |
β | gold.dim_products |
product_number |
silver.crm_sales_details |
sls_cust_id |
β | gold.dim_customers |
customer_id |
- SQL Server (2016 or later)
- SQL Server Management Studio (SSMS) or any SQL client
- Windows OS (for
BULK INSERTfile paths)
β οΈ Important: Before running Step 3, update the file paths inproc_load_bronze.sqlto match the location of your CSV files on disk.
Step 1 β scripts/init_database.sql (Create database & schemas)
Step 2 β scripts/bronze/ddl_bronze.sql (Create bronze tables)
Step 3 β scripts/bronze/proc_load_bronze.sql (Create the bronze load procedure)
Step 4 β EXEC bronze.load_bronze (Execute β loads CSVs into bronze)
Step 5 β scripts/silver/ddl_silver.sql (Create silver tables)
Step 6 β scripts/silver/proc_load_silver.sql (Create the silver load procedure)
Step 7 β EXEC silver.load_silver (Execute β transforms bronze β silver)
Step 8 β scripts/gold/ddl_gold.sql (Create gold star schema views)
Step 9 β tests/quality_checks_silver.sql (Validate silver layer)
Step 10 β tests/quality_checks_gold.sql (Validate gold layer)
Once the warehouse is set up, query the Gold layer views directly for analytics:
-- Top 10 customers by total sales
SELECT TOP 10
c.first_name,
c.last_name,
c.country,
SUM(f.sales_amount) AS total_sales,
COUNT(f.order_number) AS total_orders
FROM gold.fact_sales f
JOIN gold.dim_customers c ON f.customer_key = c.customer_key
GROUP BY c.first_name, c.last_name, c.country
ORDER BY total_sales DESC;
-- Sales by product category
SELECT
p.category,
p.subcategory,
SUM(f.sales_amount) AS total_sales,
SUM(f.quantity) AS total_quantity
FROM gold.fact_sales f
JOIN gold.dim_products p ON f.product_key = p.product_key
GROUP BY p.category, p.subcategory
ORDER BY total_sales DESC;
-- Monthly sales trend
SELECT
YEAR(f.order_date) AS order_year,
MONTH(f.order_date) AS order_month,
SUM(f.sales_amount) AS monthly_sales,
COUNT(DISTINCT f.order_number) AS total_orders
FROM gold.fact_sales f
GROUP BY YEAR(f.order_date), MONTH(f.order_date)
ORDER BY order_year, order_month;- βοΈ Primary key uniqueness & NULL detection
- βοΈ Unwanted leading/trailing spaces in string fields
- βοΈ Data standardization validation (gender, marital status, product line, country)
- βοΈ Date range and order validation
- βοΈ Sales consistency:
sales = quantity Γ price
- βοΈ Surrogate key uniqueness in
dim_customersanddim_products - βοΈ Referential integrity: all
fact_salesrows link to valid dimension records
| Scope | Pattern | Example |
|---|---|---|
| Bronze/Silver Tables | <source_system>_<entity> |
crm_cust_info, erp_loc_a101 |
| Gold Views | <category>_<entity> |
dim_customers, fact_sales |
| Surrogate Keys | <table>_key |
customer_key, product_key |
| Technical Columns | dwh_<column_name> |
dwh_create_date |
| Stored Procedures | load_<layer> |
load_bronze, load_silver |
See docs/naming_conventions.md for full details.
| Technology | Purpose |
|---|---|
| SQL Server | Database engine |
| T-SQL | DDL, stored procedures, views, window functions |
| SSMS | SQL client & administration |
| BULK INSERT | CSV data ingestion |
| Medallion Architecture | Data layering pattern (Bronze β Silver β Gold) |
| Star Schema | Dimensional modeling (facts + dimensions) |
Hello, I'm Salah Gueroui, a Master's student in Computer Science passionate about Data Analytics, Business Intelligence, Data Engineering, and Artificial Intelligence.
This project demonstrates my ability to design and implement data warehouse solutions using SQL Server, including ETL pipelines, dimensional modeling, and data quality validation. I enjoy transforming raw data into valuable insights and exploring how AI can enhance decision-making and business intelligence.
I am continuously expanding my skills in data, analytics, and AI through hands-on projects and real-world challenges.
This project is for educational and portfolio purposes.