Tool: SQL (MS SQL Server)
Dataset: 25 customer records with real-world data quality issues
Goal: Clean and standardize a messy customer database
The raw customer database contained multiple data quality issues commonly found in real-world scenarios:
| Issue | Example |
|---|---|
| Duplicate records | John Doe appeared twice (ID 1 & 21) |
| Invalid emails | johndoe@gmailcom, @em@il.com, email,com |
| NULL names | Row 7 and 12 had NULL as full_name |
| Inconsistent phone formats | 987654321, 444*555*6666, 321.654.0987 |
| NULL addresses/phones | String 'NULL' instead of actual NULL |
| Special characters in names | Michael! White, Daniel! Clark, David "Owen" |
| Inconsistent date formats | 1990/12/05 vs 1985-04-23 |
| Inconsistent text case | Mixed uppercase/lowercase |
| customer_id | full_name | phone | |
|---|---|---|---|
| 1 | John Doe | johndoe@gmailcom | 123-456-7890 |
| 7 | NULL | charles.miller@email.com | 555-888-0000 |
| 10 | Daniel! Clark | danielclark@email,com | 4445556666 |
| 21 | John Doe | johndoe@gmailcom | 123-456-7890 |
| 22 | Jane, Smith | jane.smith@email.com | 987654321 |
| customer_id | full_name | phone | |
|---|---|---|---|
| 1 | john doe | johndoe@gmail.com | 123-456-7890 |
| 7 | charles miller | charles.miller@email.com | 555-888-0000 |
| 10 | daniel clark | danielclark@email.com | 444-555-6666 |
| 22 | jane smith | jane.smith@email.com | 987-765-321 |
Used ROW_NUMBER() window function with PARTITION BY to identify and delete duplicate rows based on full_name and email.
- Removed special characters (
,,!,") usingREPLACE() - Fixed NULL names by extracting from email using
PARSENAME() - Standardized to lowercase
- Fixed missing dots:
@gmailcom→@gmail.com - Fixed double
@:@em@il.com→@email.com - Fixed commas in domain:
email,com→email.com - Fixed double dots:
email..com→email.com - Set empty emails to
'unknown'
- Replaced
.and*separators with-usingTRANSLATE() - Formatted unformatted numbers to
XXX-XXX-XXXX - Set NULL/string 'NULL' phones to
'unknown'
- Replaced string
'NULL'with'unknown' - Standardized to lowercase
- Replaced
/with-:1990/12/05→1990-12-05 - Changed column data type to
DATE
- Converted to lowercase:
M→m,F→f
ROW_NUMBER()window function — duplicate detectionWITH CTE— Common Table ExpressionsREPLACE()/TRANSLATE()— string manipulationPARSENAME()— extracting name parts from emailCONCAT()/LEFT()/RIGHT()/SUBSTRING()— string formattingALTER TABLE ALTER COLUMN— data type changesINFORMATION_SCHEMA.COLUMNS— schema inspection
sql-data-cleaning/
├── cleaning.sql # Full cleaning script with comments
└── README.md
This project demonstrates ability to handle real-world dirty data — a critical skill for any data analyst role. Data cleaning typically takes 60-80% of a data analyst's time in practice.