SQL Data Cleaning Techniques β 2026 Guide (MySQL)
SQL Data Cleaning Techniques β 2026 Guide (MySQL) π§Ή
Data aaya β ab kya karo? Step-by-step SQL data cleaning process β jaise ek real data analyst kaam karta hai. Data explore karo, issues dhundho, fix karo, clean table banao. Sab MySQL queries ke saath β practical aur simple. Data Insights par.
π Data Cleaning Process β Steps:
- Step 1: Data Cleaning Kya Hai β Introduction
- Step 2: Sample Dirty Dataset β Real-world messy data
- Step 3: Data Explore β Structure & Types dekho
- Step 4: NULL Values Handle Karo
- Step 5: Duplicates Remove Karo
- Step 6: Text Standardize Karo (Case & Spaces)
- Step 7: Inconsistent Values Fix Karo
- Step 8: Dates Clean Karo
- Step 9: Data Type Convert Karo
- Step 10: Outliers Handle Karo
- Step 11: Final Clean Table Banao
Step 1: Data Cleaning Kya Hai β Introduction
π Definition: Data Cleaning is the process of detecting and fixing (or removing) inaccurate, incomplete, duplicated, and inconsistent records from a dataset to improve data quality. In real-world scenarios, 60-70% of a data analyst's time goes into cleaning data β it's the most important and most time-consuming step before analysis.
π― Explanation: Real data KABHI clean nahi aata β hamesha dirty hota hai. Missing values, duplicate entries, extra spaces, inconsistent names (Delhi, DELHI, delhi), wrong data types, outliers β yeh sab common issues hain. "Garbage In, Garbage Out" β agar dirty data par analysis karoge toh wrong insights aayenge. Pehle clean karo, phir analyze karo.
π Data Cleaning Workflow β Real Process:
Data Analyst ka Real Data Cleaning Process:
Step 1: Data aaya (CSV, Excel, Database)
β
Step 2: EXPLORE β Structure dekho (columns, data types)
β
Step 3: NULL check karo β kahan data missing hai?
β
Step 4: DUPLICATES check karo β same data repeat toh nahi?
β
Step 5: TEXT clean karo β spaces, case standardize
β
Step 6:
VALUES fix karo β inconsistent entries (M/Male/male)
β
Step 7: DATES fix karo β format standardize
β
Step 8: DATA TYPES fix karo β string mein numbers etc.
β
Step 9: OUTLIERS check karo β unrealistic
values
β
Step 10: CLEAN TABLE banao β production-ready data
Time Split:
π§Ή Data Cleaning: ~60-70% time
π Analysis: ~20-25% time
π Visualization: ~10-15% time
π Common Data Issues:
| Issue Type | Example | SQL Fix |
|---|---|---|
| Missing Values | email = NULL | IFNULL, COALESCE |
| Duplicates | Same person 2 times | ROW_NUMBER + DELETE |
| Whitespace | " Jatin " (extra spaces) | TRIM() |
| Inconsistent Case | DELHI, Delhi, delhi | UPPER(), LOWER() |
| Inconsistent Values | M, Male, male, MALE | CASE WHEN, REPLACE |
| Wrong Data Types | salary = "50000" (string) | CAST, CONVERT |
| Invalid Dates | "31/13/2025" (wrong month) | STR_TO_DATE() |
| Outliers | salary = 99999999 (unrealistic) | Statistical detection |
Step 2: Sample Dirty Dataset β Real-World Messy Data
π Definition: Before cleaning, we need a realistic dirty dataset. Below is a "messy employees" table β it has every common data quality issue. We'll use this SAME table throughout all cleaning steps.
π― Explanation: Yeh table intentionally messy hai β jaise real companies ka data hota hai. Extra spaces, mixed case, duplicates, NULL values, inconsistent gender values, wrong dates, outliers β sab kuch hai. In sabko step-by-step fix karenge.
π» Create the Dirty Dataset:
-- Create messy employees table
CREATE TABLE employees_dirty ( emp_id INT, emp_name VARCHAR(100), email VARCHAR(100), gender VARCHAR(20), department VARCHAR(50), city VARCHAR(50), salary VARCHAR(20), join_date VARCHAR(20), phone VARCHAR(20) );
INSERT INTO employees_dirty
VALUES
(1, ' Jatin Kumar ', 'jatin@gmail.com', 'Male', 'IT', 'Delhi', '50000', '2024-01-15', '9876543210'),
(2, 'PRIYA PATEL', 'priya@gmail.com', 'F', ' Sales ', 'MUMBAI', '60000', '15/03/2024', '9123456780'),
(3, 'rahul verma', 'rahul@yahoo.com', 'm', 'IT', 'delhi', '55000', '2024-02-20', NULL),
(4, ' Neha Gupta', NULL, 'Female', 'HR', 'Delhi', '48000', '20-Apr-2024', '9988776655'),
(5, 'Vikram Singh', 'vikram@gmail.com', 'MALE', 'sales', 'Chennai', '9999999', '2024-03-10', '9876543210'),
(6, ' Jatin Kumar ', 'jatin@gmail.com', 'Male', 'IT', 'Delhi', '50000', '2024-01-15', '9876543210'),
(7, 'Sneha Iyer', 'sneha@outlook.com', 'female', 'Marketing', 'bangalore', '52000', '2024/05/25', '8877665544'),
(8, 'Arjun Das', 'arjun@gmail.com', NULL, 'IT ', 'Kolkata', '47000', '2024-06-18', '7766554433'),
(9, 'Meera Nair', 'meera@gmail.com', 'F', NULL, 'Chennai', '0', '2024-07-01', '6655443322'),
(10, 'RAHUL VERMA', 'rahul@yahoo.com', 'Male', 'IT', 'DELHI', '55000', '2024-02-20', NULL);
π Dirty Data Preview:
SELECT * FROM employees_dirty;
| id | emp_name | gender | department | city | salary | join_date | phone | |
|---|---|---|---|---|---|---|---|---|
| 1 | ' Jatin Kumar ' | jatin@gmail.com | Male | IT | Delhi | 50000 | 2024-01-15 | 9876543210 |
| 2 | 'PRIYA PATEL' | priya@gmail.com | F | ' Sales ' | MUMBAI | 60000 | 15/03/2024 | 9123456780 |
| 3 | 'rahul verma' | rahul@yahoo.com | m | IT | delhi | 55000 | 2024-02-20 | NULL |
| 4 | ' Neha Gupta' | NULL | Female | HR | Delhi | 48000 | 20-Apr-2024 | 9988776655 |
| 5 | 'Vikram Singh' | vikram@gmail.com | MALE | sales | Chennai | 9999999 | 2024-03-10 | 9876543210 |
| 6 | ' Jatin Kumar ' | jatin@gmail.com | Male | IT | Delhi | 50000 | 2024-01-15 | 9876543210 |
| 7 | 'Sneha Iyer' | sneha@outlook.com | female | Marketing | bangalore | 52000 | 2024/05/25 | 8877665544 |
| 8 | 'Arjun Das' | arjun@gmail.com | NULL | 'IT ' | Kolkata | 47000 | 2024-06-18 | 7766554433 |
| 9 | 'Meera Nair' | meera@gmail.com | F | NULL | Chennai | 0 | 2024-07-01 | 6655443322 |
| 10 | 'RAHUL VERMA' | rahul@yahoo.com | Male | IT | DELHI | 55000 | 2024-02-20 | NULL |
Issues spotted: β Names: extra spaces, mixed case (PRIYA, rahul, Neha) β Gender: Male, F, m, Female, MALE, female, NULL β Department: extra spaces (IT , ' Sales '), NULL β City: Delhi, delhi, DELHI, MUMBAI, bangalore (inconsistent) β Salary: VARCHAR type, outlier (9999999), zero (0) β Dates: 4 different formats! (YYYY-MM-DD, DD/MM/YYYY, DD-Mon-YYYY, YYYY/MM/DD) β Duplicates: Row 1 = Row 6, Row 3 β Row 10 β NULLs: email, gender, department, phone
Step 3: Data Explore β Structure & Types Dekho
π Definition: Before cleaning, you must understand the dataset β how many rows, what columns exist, what data types are set, and what the data looks like. This step tells you WHAT to clean.
π― Explanation: Cleaning se pehle data ko samjho β "kitne rows hain? Columns kya hain? Data types kya hain? Kahan NULL hai? Kitne unique values hain?" Yeh exploration step hai β cleaning START karne se pehle HAMESHA yeh karo. Doctor bhi pehle diagnose karta hai, phir treatment shuru karta hai.
π» Check Table Structure:
-- Step 3.1: Table structure β columns aur data types DESCRIBE employees_dirty; | Field | Type | Null | Key | Default |
|---|---|---|---|---|
| emp_id | int | YES | NULL emp_name | varchar(100) |
| YES | NULL email | varchar(100) | YES | NULL gender |
| varchar(20) | YES | NULL department | varchar(50) | YES |
| NULL city | varchar(50) | YES | NULL salary | varchar(20) |
| YES | NULL | varchar(20) | YES | NULL |
salary VARCHAR hai! Should be INT join_date date bhi VARCHAR! Should be DATE phone varchar(20) YES NULL
π» Check Total Rows & Basic Stats:
-- Step 3.2: Total rows
SELECT COUNT(*) AS total_rows
FROM employees_dirty;
-- Result: 10
-- Step 3.3: NULL count per column
SELECT
SUM(CASE WHEN emp_name IS NULL THEN 1 ELSE 0 END) AS null_name,
SUM(CASE WHEN email IS NULL THEN 1 ELSE 0 END) AS null_email,
SUM(CASE WHEN gender IS NULL THEN 1 ELSE 0 END) AS null_gender,
SUM(CASE WHEN department IS NULL THEN 1 ELSE 0 END) AS null_dept,
SUM(CASE WHEN phone IS NULL THEN 1 ELSE 0 END) AS null_phone
FROM employees_dirty;
| null_name | null_email | null_gender | null_dept | null_phone |
|---|---|---|---|---|
| 0 | 1 | 1 | 1 | 2 |
π» Check Unique Values β Spot Inconsistencies:
-- Step 3.4: Check unique values in categorical columns
SELECT DISTINCT gender
FROM employees_dirty; gender
values: Male, F, m, Female, MALE, female, NULL β 7 different
values for just 2 categories! NEEDS CLEANINGSELECT DISTINCT city
FROM employees_dirty;
SELECT DISTINCT department
FROM employees_dirty;city
values: Delhi, MUMBAI, delhi, Chennai, bangalore, Kolkata,
DELHI β Delhi appears 3 times in different cases! department
values: IT, ' Sales ', HR, sales, Marketing, 'IT ', NULL β IT and sales have spaces and case issuesStep 4: NULL Values Handle Karo
π Definition: NULL means missing/unknown data. Handling NULLs is the first cleaning step β you can either FILL them with a default value, FILL with calculated value, or REMOVE rows with NULLs depending on the situation.
π― Explanation: NULL = "pata nahi" β missing data. 3 options hain: (1) Default value se replace karo (jaise "Unknown"). (2) Delete karo woh rows agar bahut critical data missing hai. (3) Calculated value fill karo (jaise average salary). Kaunsa option choose karna hai β depends on column importance aur business context. Email NULL hai toh maybe "Unknown" fill karo. But agar primary key NULL hai toh row delete karo.
π» Find NULL Values:
-- Find rows where email is NULL
SELECT emp_id, emp_name, email
FROM employees_dirty
WHERE email IS NULL; | emp_id | emp_name | |
|---|---|---|
| 4 | ' Neha Gupta' | NULL |
π» Fill NULLs with Default Value:
-- Method 1: IFNULL β replace NULL with default (SELECT only)
SELECT emp_id, emp_name, IFNULL(email, 'not_provided@company.com') AS email, IFNULL(gender, 'Unknown') AS gender,
IFNULL(department, 'Unassigned') AS department, IFNULL(phone, 'N/A') AS phone
FROM employees_dirty;
-- Method 2: COALESCE β try multiple fallback values
SELECT
emp_id,
COALESCE(email, phone, 'No Contact') AS contact_info
FROM employees_dirty;
-- Pehle email check karo, NULL toh phone, woh bhi NULL toh 'No Contact'
π» Actually UPDATE the Table β Fix NULLs Permanently:
-- Fix NULL emails
UPDATE employees_dirty
SET email = 'not_provided@company.com'
WHERE email IS NULL;
-- Fix NULL gender
UPDATE employees_dirty
SET gender = 'Unknown'
WHERE gender IS NULL;
-- Fix NULL department
UPDATE employees_dirty
SET department = 'Unassigned'
WHERE department IS NULL;
-- Fix NULL phone
UPDATE employees_dirty
SET phone = 'N/A'
WHERE phone IS NULL;
π After NULL Handling β Verify:
-- Verify: No NULLs remaining
SELECT SUM(CASE WHEN email IS NULL THEN 1 ELSE 0 END) AS null_email,
SUM(CASE WHEN gender IS NULL THEN 1 ELSE 0 END) AS null_gender,
SUM(CASE WHEN department IS NULL THEN 1 ELSE 0 END) AS null_dept,
SUM(CASE WHEN phone IS NULL THEN 1 ELSE 0 END) AS null_phone
FROM employees_dirty; β
All NULLs handled!
β’
WHERE email = NULL GALAT hai β kaam nahi karega! Hamesha WHERE email IS NULL use karo.β’ Har NULL ko blindly 0 ya empty string se replace mat karo β business context samjho. Salary NULL hai toh 0 replace karna misleading hai (salary 0 aur salary unknown alag hain).
β’ UPDATE karne se pehle SELECT se verify karo ki sahi rows target ho rahi hain.
Step 5: Duplicates Remove Karo
π Definition: Duplicate rows are records that appear more than once β either exactly same or semantically same (like "Jatin Kumar" and " JATIN KUMAR " β different text, same person). Duplicates inflate counts, skew averages, and corrupt analysis.
π― Explanation: Humare data mein Row 1 aur Row 6 exact duplicate hain (same Jatin Kumar). Row 3 (rahul verma) aur Row 10 (RAHUL VERMA) β same person but different case. Pehle identify karo, phir ek rakhke baaki delete karo. ROW_NUMBER window function se best kaam hota hai β har duplicate group mein ek ko rakhke baaki remove.
π» Find Duplicate Rows:
-- Method 1: Find exact duplicates using GROUP BY
SELECT LOWER(TRIM(emp_name)) AS clean_name, email, COUNT(*) AS count
FROM employees_dirty
GROUP BY LOWER(TRIM(emp_name)), email
HAVING COUNT(*) > 1; | clean_name | count | |
|---|---|---|
| jatin kumar | jatin@gmail.com | 2 |
Row 1 and Row 6 rahul verma Row 3 and Row 10 rahul@yahoo.com 2
π» Identify Duplicates with ROW_NUMBER:
-- Method 2: ROW_NUMBER to tag duplicates
SELECT *, ROW_NUMBER() OVER ( PARTITION BY LOWER(TRIM(emp_name)), email ORDER BY emp_id ) AS row_num
FROM employees_dirty; | emp_id | emp_name | row_num | |
|---|---|---|---|
| 1 | ' Jatin Kumar ' | jatin@gmail.com | 1 |
| ' Jatin Kumar ' | jatin@gmail.com | 2 | 'rahul verma' |
| rahul@yahoo.com | 1 | 'RAHUL VERMA' | rahul@yahoo.com |
KEEP (first occurrence) 6 DELETE (duplicate!) 3 KEEP 10 DELETE ...other rows... KEEP (unique) 2 1
π» Delete Duplicates β Keep First Occurrence:
-- Delete duplicates β keep lowest emp_id per group DELETE FROM employees_dirty WHERE emp_id NOT IN (
SELECT min_id
FROM ( SELECT MIN(emp_id) AS min_id FROM employees_dirty GROUP BY LOWER(TRIM(emp_name)), email ) AS temp );
-- Verify: Check row count after deletion
SELECT COUNT(*) AS remaining_rows
FROM employees_dirty;
-- Before: 10 rows β After: 8 rows (2 duplicates removed β
)
β’ Sirf exact match se duplicates dhundhna β "Jatin Kumar" aur "JATIN KUMAR" alag dikhte hain but same person. TRIM + LOWER lagao pehle comparison ke liye.
β’ DELETE karne se pehle SELECT se verify karo β galat rows delete ho gayi toh recover mushkil. Hamesha backup lo pehle:
CREATE TABLE employees_backup AS SELECT * FROM employees_dirty;β’ Kaunsa row RAKHNA hai β pehla (MIN id) ya aakhri (MAX id)? Business rule decide karo. Usually pehla entry rakhte hain.
Step 6: Text Standardize Karo β Case & Spaces
π Definition: Text standardization means making text data consistent β removing extra spaces (leading, trailing, double spaces), and standardizing letter case (uppercase/lowercase). Without this, "Delhi", "delhi", "DELHI", and " Delhi " are treated as DIFFERENT values β breaking GROUP BY, JOINs, and filtering.
π― Explanation: Humare data mein: names mein extra spaces (" Jatin Kumar "), cities mein mixed case (Delhi, delhi, DELHI, MUMBAI, bangalore), departments mein spaces (" Sales ", "IT "). TRIM se spaces hataenge, UPPER/LOWER se case standardize karenge. Yeh step bahut important hai β agar city column mein "Delhi" 3 alag tarike se likha hai toh GROUP BY city mein 3 groups banenge instead of 1!
π» Before β See the Problem:
-- See the problem: same city, different text
SELECT city, COUNT(*) AS count
FROM employees_dirty
GROUP BY city; city β count
Delhi β 1 MUMBAI 1 delhi β 1 Chennai β 2 bangalore β 1 Kolkata β 1 DELHI β 1
β Delhi appears 3 times! Should be ONE
group with 3 employees.
π» Fix Names β TRIM + Proper Case:
-- Fix 6.1: Remove leading/trailing spaces from names
UPDATE employees_dirty
SET emp_name = TRIM(emp_name);
-- Fix 6.2: Proper Case for names β MySQL doesn't have INITCAP
-- We'll use CONCAT + UPPER(LEFT) + LOWER(SUBSTRING) for first word
-- For simple fix, convert to title case manually:
UPDATE employees_dirty
SET emp_name = CONCAT(
UPPER(LEFT(TRIM(emp_name), 1)),
LOWER(SUBSTRING(TRIM(emp_name), 2))
);
π» Fix City β Proper Case:
-- Fix 6.3: Standardize city β Proper Case (capitalize first letter)
UPDATE employees_dirty
SET city = CONCAT( UPPER(LEFT(TRIM(city), 1)), LOWER(SUBSTRING(TRIM(city), 2)) );π» Fix Department β TRIM + Proper Case:
-- Fix 6.4: Clean department β remove spaces + standardize case
UPDATE employees_dirty
SET department = CONCAT( UPPER(LEFT(TRIM(department), 1)), LOWER(SUBSTRING(TRIM(department), 2)) );π After β Verify Standardization:
-- Check city after cleaning
SELECT city, COUNT(*) AS count
FROM employees_dirty
GROUP BY city; BEFORE: AFTER: city β count city β count
Delhi β 1 Delhi β 3 β All merged! β
MUMBAI β 1 Mumbai β 1 β
delhi β 1 Chennai β 2 β
Chennai β 2 Bangalore β 1 β
bangalore β 1 Kolkata β 1 β
Kolkata β 1 DELHI β 1
7 groups β 5 groups! Delhi properly consolidated!
-- Check all text columns now
SELECT emp_id, emp_name, department, city
FROM employees_dirty;emp_id β emp_name β department β city
1 | Jatin kumar β It β Delhi β
(was ' Jatin Kumar ')
2 β Priya patel β Sales β Mumbai β
(was 'PRIYA PATEL', 'MUMBAI')
3 β Rahul verma β It β Delhi β
(was 'rahul verma', 'delhi')
4 β Neha gupta β Hr β Delhi β
(was ' Neha Gupta')
5 β Vikram singhβ Sales β Chennai β
(was 'sales')
7 β Sneha iyer β Marketing β Bangalore β
(was 'bangalore')
8 β Arjun das β It β Kolkata β
(was 'IT ')
9 β Meera nair β Unassigned β Chennai β
All text standardized β no extra spaces, consistent case! πβ’ TRIM sirf leading/trailing spaces hatata hai β beech ke double spaces nahi. "Jatin Kumar" (2 spaces) ke liye
REPLACE(name, ' ', ' ') use karo.β’ MySQL mein INITCAP function nahi hai (PostgreSQL mein hai) β isliye CONCAT + UPPER + LOWER combination use karni padti hai. Multi-word names (Jatin Kumar) ke liye manual handling ya stored procedure chahiye.
β’ ALWAYS pehle SELECT se output check karo, phir UPDATE karo. Galat UPDATE se data corrupt hota hai.
Step 7: Inconsistent Values Fix Karo
π Definition: Inconsistent values mean the same thing is represented in multiple ways β like gender stored as "Male", "M", "m", "MALE", "male" β all should be ONE standard value. This commonly happens in categorical columns (gender, status, department, country) where data is entered manually without dropdown validation.
π― Explanation: Humare data mein gender column sabse bura hai β Male, F, m, Female, MALE, female, Unknown β 7 different values for sirf 2 categories! GROUP BY karo toh 7 groups banenge instead of 2. Fix kaise? CASE WHEN se sab ko standardize karo β "M", "m", "Male", "MALE" β sabko "Male" banao. "F", "female", "Female" β "Female" banao. REPLACE simple cases mein kaam karta hai, CASE WHEN complex mapping ke liye.
π» Before β See the Inconsistency:
-- Check current gender values
SELECT gender, COUNT(*) AS count
FROM employees_dirty
GROUP BY gender; | gender | count |
|---|---|
| Male | 1 |
| F | 2 |
| m | 1 |
| Female | 1 |
| MALE | 1 |
| female | 1 |
| Unknown | 1 |
| β | 7 |
| different values β should be only | 3: |
Male, Female, Unknown
π» Fix Gender β CASE WHEN Standardization:
-- Step 1: Preview the fix first (SELECT β don't UPDATE yet!) SELECT emp_id, emp_name, gender AS old_gender, CASE WHEN LOWER(TRIM(gender)) IN ('m', 'male') THEN 'Male' WHEN LOWER(TRIM(gender)) IN ('f', 'female') THEN 'Female' ELSE 'Unknown' END AS new_gender FROM employees_dirty; | emp_id | emp_name | old_gender | new_gender |
|---|---|---|---|
| 1 | Jatin kumar | Male | Male β |
| 2 | Priya patel | F | Female β (was F) |
| 3 | Rahul verma | m | Male β (was m) |
| 4 | Neha gupta | Female | Female β |
| 5 | Vikram singh | MALE | Male β (was MALE) |
| 7 | Sneha iyer | female | Female β (was female) |
| 8 | Arjun das | Unknown | Unknown β |
| 9 | Meera nair | F | Female β (was F) Preview looks correct! Now UPDATE. |
π» Apply the Fix β UPDATE:
-- Step 2: Actually UPDATE the table
UPDATE employees_dirty
SET gender = CASE
WHEN LOWER(TRIM(gender)) IN ('m', 'male')
THEN 'Male'
WHEN LOWER(TRIM(gender)) IN ('f', 'female')
THEN 'Female'
ELSE 'Unknown'
END;
-- Verify after update
SELECT gender, COUNT(*) AS count
FROM employees_dirty
GROUP BY gender;
| BEFORE: AFTER: gender | count gender | count |
|---|
| Male | 1 Male | 3 β F | 2 Female | 4 β m | 1 Unknown | 1 β Female | 1 MALE | 1 7 groups β 3 groups! Clean! π female | 1 Unknown | 1 |
|---|
π» REPLACE β Simple Text Substitution:
-- REPLACE is good for simple substitutions -- Example: Fix department abbreviations
UPDATE employees_dirty
SET department = REPLACE(department, 'It', 'IT')
WHERE department = 'It';
UPDATE employees_dirty
SET department = REPLACE(department, 'Hr', 'HR')
WHERE department = 'Hr';
-- Verify
SELECT DISTINCT department
FROM employees_dirty;
department
IT β
(was It) Sales β
HR β
(was Hr) Marketing β
Unassigned β
β’ Directly UPDATE karna bina SELECT se preview kiye β galat mapping ho gayi toh data corrupt. Hamesha pehle SELECT + CASE WHEN se dekho output, phir UPDATE karo.
β’ REPLACE se hamesha dhyaan rakho β
REPLACE('Marketing', 'IT', 'Information Technology') se unexpected change ho sakta hai agar substring match ho jaaye. WHERE clause se specific rows target karo.β’ Naye inconsistent values future mein bhi aa sakte hain β long-term fix ke liye CHECK constraint ya ENUM data type use karo table mein.
Step 8: Dates Clean Karo
π Definition: Date cleaning involves converting dates from various string formats into a standard DATE type. Real data often has dates in multiple formats β "2024-01-15", "15/03/2024", "20-Apr-2024", "2024/05/25" β all in the same column. We need to standardize them to one format (YYYY-MM-DD) and convert from VARCHAR to proper DATE type.
π― Explanation: Humare data mein join_date column VARCHAR hai (Step 3 mein dekha tha) aur 4 different formats hain β "2024-01-15" (YYYY-MM-DD), "15/03/2024" (DD/MM/YYYY), "20-Apr-2024" (DD-Mon-YYYY), "2024/05/25" (YYYY/MM/DD). Pehle sab ko ek format mein laao, phir column ka data type DATE mein convert karo. STR_TO_DATE() MySQL ka function hai β string ko date mein convert karta hai format specify karke.
π» Before β Check Current Date Formats:
-- See all different date formats
SELECT emp_id, emp_name, join_date
FROM employees_dirty; 4 different formats! Need standardization.
π MySQL Date Format Codes:
| Code | Meaning | Example |
|---|---|---|
| %Y | 4-digit year | 2024 |
| %m | Month (01-12) | 03 |
| %d | Day (01-31) | 15 |
| %b | Abbreviated month name | Apr, Jan, Dec |
π» Fix Each Date Format β Step by Step:
-- Fix 8.1: DD/MM/YYYY format (e.g., "15/03/2024")
UPDATE employees_dirty
SET join_date = DATE_FORMAT( STR_TO_DATE(join_date, '%d/%m/%Y'), '%Y-%m-%d' )
WHERE join_date LIKE '%/%' AND join_date NOT LIKE '____/%';
-- Matches "15/03/2024" but NOT "2024/05/25"
-- Fix 8.2: DD-Mon-YYYY format (e.g., "20-Apr-2024")
UPDATE employees_dirty
SET join_date = DATE_FORMAT(
STR_TO_DATE(join_date, '%d-%b-%Y'),
'%Y-%m-%d'
)
WHERE join_date REGEXP '[0-9]{2}-[A-Za-z]{3}-[0-9]{4}';
-- Matches "20-Apr-2024" pattern
-- Fix 8.3: YYYY/MM/DD format (e.g., "2024/05/25")
UPDATE employees_dirty
SET join_date = REPLACE(join_date, '/', '-')
WHERE join_date LIKE '____/%';
-- "2024/05/25" β "2024-05-25" (simple slash to hyphen)
π After β All Dates Standardized:
-- Verify all dates are now YYYY-MM-DD format
SELECT emp_id, emp_name, join_date
FROM employees_dirty; All dates in YYYY-MM-DD format! π
β’ STR_TO_DATE mein wrong format code dena β "15/03/2024" ke liye
'%d/%m/%Y' chahiye, '%m/%d/%Y' diya toh March 15 ki jagah random date banega ya error aayega.β’ DD/MM aur MM/DD confuse karna β "03/04/2024" kya hai? March 4 ya April 3? Source data ki documentation check karo β assume mat karo.
β’ Column abhi bhi VARCHAR hai β dates standardize ho gayi hain but type convert karna next step mein karenge.
Step 9: Data Type Convert Karo
π Definition: Data Type Conversion means changing columns from wrong types to correct types. Common issues: salary stored as VARCHAR instead of INT, dates as VARCHAR instead of DATE. Wrong data types prevent mathematical operations (SUM on text fails), date functions (DATEDIFF on text fails), and proper sorting.
π― Explanation: Humare data mein salary VARCHAR(20) hai β string hai, number nahi! SUM(salary) karo toh galat result aayega ya error. join_date bhi VARCHAR hai β DATEDIFF(), YEAR() jaisi functions kaam nahi karengi. ALTER TABLE se column ka data type change karenge β VARCHAR β INT (salary), VARCHAR β DATE (join_date). Yeh step cleaning ke baad karo β pehle values clean hone chahiye, warna type conversion fail hoga.
π» Before β Check Current Types:
-- Current types (from Step 3) DESCRIBE employees_dirty; salary β varchar(20) β Should be INT or DECIMAL join_date β varchar(20) β Should be DATEπ» Test Before Converting β CAST Preview:
-- Test salary conversion first (SELECT β preview)
SELECT emp_id, emp_name, salary AS salary_varchar, CAST(salary AS UNSIGNED) AS salary_int
FROM employees_dirty;
-- Test date conversion
SELECT
emp_id,
join_date AS date_varchar,
CAST(join_date AS DATE) AS date_proper
FROM employees_dirty;
| emp_id | salary_varchar | salary_int | date_varchar | date_proper |
|---|---|---|---|---|
| 1 | '50000' | 50000 | '2024-01-15' | 2024-01-15 2 |
| '60000' | 60000 | '2024-03-15' | 2024-03-15 5 | '9999999' |
| 9999999 | '2024-03-10' | 2024-03-10 9 | '0' | 0 |
'2024-07-01' 2024-07-01 β Conversion looks correct! Safe to ALTER.
π» ALTER TABLE β Change Data Types Permanently:
-- Convert salary from VARCHAR to INT ALTER TABLE employees_dirty MODIFY COLUMN salary INT;
-- Convert join_date from VARCHAR to DATE
ALTER TABLE employees_dirty
MODIFY COLUMN join_date DATE;
-- Verify new types
DESCRIBE employees_dirty;
| Field | Type | BEFORE β AFTER |
|---|---|---|
| salary | int | varchar(20) β int β join_date |
date varchar(20) β date β
π» Now Date Functions Work!
-- Date functions work now! (weren't possible with VARCHAR)
SELECT emp_name, join_date, YEAR(join_date) AS join_year,
MONTH(join_date) AS join_month, DATEDIFF(CURDATE(), join_date) AS days_since_joining
FROM employees_dirty;
-- Salary aggregation works now!
SELECT
SUM(salary) AS total_salary,
AVG(salary) AS avg_salary,
MIN(salary) AS min_salary,
MAX(salary) AS max_salary
FROM employees_dirty;
β’ ALTER TABLE karne se pehle values clean nahi kiye β agar salary mein "fifty thousand" jaise text hai toh INT conversion fail hoga (Data truncated error).
β’ HAMESHA pehle CAST() se SELECT mein test karo, sab clean dikh raha hai toh phir ALTER karo.
β’ DATE conversion fail hoga agar date format standardize nahi kiya (Step 8 pehle karo, phir Step 9).
Step 10: Outliers Handle Karo
π Definition: Outliers are values that are significantly different from other values in the dataset β either unrealistically high or low. Examples: salary = 9999999 (data entry error), salary = 0 (missing but entered as zero). Outliers skew averages, totals, and other statistical measures. We need to detect them, investigate why they exist, and decide whether to fix, cap, or remove them.
π― Explanation: Humare data mein salary column mein 2 outliers hain β Vikram ka salary 9999999 (data entry error β realistic nahi) aur Meera ka salary 0 (maybe missing value ko zero enter kiya). Average salary calculate karo with outliers β bahut zyada inflated aayega. Pehle detect karo (statistical methods ya business rules se), phir decide karo β remove karo, cap karo, ya NULL banao.
π» Detect Outliers β Statistical Method:
-- Method 1: Check salary statistics β spot extreme values
SELECT COUNT(*) AS total, MIN(salary) AS min_sal, MAX(salary) AS max_sal,
ROUND(AVG(salary), 0) AS avg_sal, ROUND(STDDEV(salary), 0) AS std_dev
FROM employees_dirty; β avg salary βΉ12.89L? Unrealistic!
β min = 0 (probably missing data entered as zero)
β max = 9999999 (data entry error)
β STDDEV bahut bada β outliers ki wajah se
π» Find Outlier Rows:
-- Method 2: Business rule β realistic salary range -- Assume: Normal salary range is βΉ10,000 to βΉ5,00,000
SELECT emp_id, emp_name, salary, CASE
WHEN salary = 0
THEN 'ZERO (possibly missing)'
WHEN salary < 10000
THEN 'TOO LOW'
WHEN salary > 500000
THEN 'TOO HIGH'
ELSE 'NORMAL'
END AS status
FROM employees_dirty
ORDER BY salary; | emp_id | emp_name | salary | status |
|---|---|---|---|
| 9 | Meera nair | 0 | ZERO (possibly missing) β οΈ 8 |
| Arjun das | 47000 | NORMAL β 4 | Neha gupta |
| 48000 | NORMAL β 1 | Jatin kumar | 50000 |
| NORMAL β 7 | Sneha iyer | 52000 | NORMAL β 3 |
| Rahul verma | 55000 | NORMAL β 2 | Priya patel |
| 60000 | NORMAL β 5 | Vikram singh | 9999999 |
TOO HIGH β οΈ
π» Fix Outliers:
-- Option 1: Set outliers to NULL (safest β mark as unknown)
UPDATE employees_dirty
SET salary = NULL
WHERE salary = 0 OR salary > 500000;
-- Option 2: Replace with average (imputation)
-- First calculate avg WITHOUT outliers
SET @avg_salary = (
SELECT ROUND(AVG(salary), 0)
FROM employees_dirty
WHERE salary BETWEEN 10000 AND 500000
);
UPDATE employees_dirty
SET salary = @avg_salary
WHERE salary IS NULL;
-- Verify after fixing outliers
SELECT
MIN(salary) AS min_sal,
MAX(salary) AS max_sal,
ROUND(AVG(salary), 0) AS avg_sal
FROM employees_dirty;
BEFORE (with outliers): AFTER (outliers fixed): min: 0, max: 9999999 min: 47000,
max: 60000 avg: βΉ12,89,000 (WRONG!) avg: βΉ52,000 (REALISTIC β
)β’ Outliers ko blindly delete karna β pehle investigate karo KYUN outlier hai. Kya data entry error hai? Kya legitimate high earner hai (CEO)? Context samjho.
β’ Zero ko hamesha outlier mat maano β kuch cases mein 0 valid hai (new joinee ka bonus = 0). Yahan 0 salary clearly invalid hai β isliye treat kiya.
β’ Average se replace karna β agar bahut zyada outliers hain toh median better hai average se (median outlier-resistant hota hai).
Step 11: Final Clean Table Banao
π Definition: The final step is to create a clean, production-ready table from your cleaned data. This table should have correct data types, no NULLs (or handled NULLs), no duplicates, standardized text, consistent values, and proper constraints. You can either UPDATE the existing table (like we did) or CREATE a new clean table from the dirty one.
π― Explanation: Ab tak humne step-by-step sab fix kiya β NULLs, duplicates, text, dates, types, outliers. Ab final clean table verify karte hain aur ek production-ready version banate hain. Agar original table modify nahi karni thi β toh CREATE TABLE employees_clean AS SELECT ... se naya clean table bana sakte ho without touching original.
π» Final Verification β Data Quality Check:
-- Final Quality Check β all issues resolved?
SELECT COUNT(*) AS total_rows, COUNT(DISTINCT LOWER(emp_name)) AS unique_employees,
COUNT(DISTINCT gender) AS gender_values, COUNT(DISTINCT department) AS dept_values,
COUNT(DISTINCT city) AS city_values, MIN(salary) AS min_salary,
MAX(salary) AS max_salary, ROUND(AVG(salary), 0) AS avg_salary,
MIN(join_date) AS earliest_date, MAX(join_date) AS latest_date
FROM employees_dirty; total_rows: 8 β
(was 10, 2 duplicates removed) unique_employees: 8 β
(no duplicates) gender_values: 3 β
(Male, Female, Unknown β was 7!) dept_values: 5 β
(IT, Sales, HR, Marketing, Unassigned) city_values: 5 β
(was 7 β Delhi consolidated) min_salary: 47000 β
(was 0) max_salary: 60000 β
(was 9999999) avg_salary: 52000 β
(was 12,89,000 β realistic now!) earliest_date: 2024-01-15 β
(proper DATE format) latest_date: 2024-07-01 β
π» Create Clean Production Table:
-- Method 1: Create new clean table from dirty (if you want to keep original) CREATE TABLE employees_clean AS
SELECT emp_id, TRIM(emp_name) AS emp_name, email, gender,
department, city, salary, join_date, phone
FROM employees_dirty
ORDER BY emp_id;
-- Method 2: Add constraints to prevent future dirty data
ALTER TABLE employees_clean
MODIFY COLUMN emp_id INT PRIMARY KEY,
MODIFY COLUMN emp_name VARCHAR(100) NOT NULL,
MODIFY COLUMN email VARCHAR(100) NOT NULL,
MODIFY COLUMN salary INT NOT NULL,
MODIFY COLUMN join_date DATE NOT NULL;
π Final Clean Data β Before vs After:
-- View final clean data
SELECT *
FROM employees_clean; π CLEAN DATA β Production Ready!
π Complete Cleaning Summary β What We Fixed:
| Step | Issue | Before | After | SQL Used |
|---|---|---|---|---|
| Step 4 | NULL values | 5 NULLs across columns | 0 NULLs β all filled | IFNULL, UPDATE |
| Step 5 | Duplicates | 10 rows (2 duplicates) | 8 rows (unique) | GROUP BY, DELETE |
| Step 6 | Text (case + spaces) | Delhi/delhi/DELHI, extra spaces | Standardized β Delhi, Mumbai | TRIM, UPPER, LOWER |
| Step 7 | Inconsistent values | 7 gender variants | 3 clean values | CASE WHEN, REPLACE |
| Step 8 | Dates | 4 different formats | YYYY-MM-DD standard | STR_TO_DATE, DATE_FORMAT |
| Step 9 | Data types | salary=VARCHAR, date=VARCHAR | salary=INT, date=DATE | ALTER TABLE, CAST |
| Step 10 | Outliers | salary: 0 and 9999999 | Replaced with avg (52000) | CASE WHEN, AVG, UPDATE |
| Step 11 | Final table | 10 dirty rows | 8 clean production rows | CREATE TABLE AS SELECT |
β’ Original table backup nahi lena cleaning se pehle β agar kuch galat hua toh revert nahi ho paayega. Hamesha pehle:
CREATE TABLE backup AS SELECT * FROM original;β’ Constraints (NOT NULL, PRIMARY KEY) cleaning ke pehle lagana β INSERT/UPDATE fail honge. Pehle clean karo, phir constraints add karo.
β’ Clean table ko directly production mein use karna bina testing ke β pehle SELECT queries chala ke verify karo ki sab sahi hai, phir use karo analysis mein.
π SQL Data Cleaning Guide β Complete!
11 steps mein dirty data ko clean, production-ready data mein convert kiya β NULL handling, duplicate removal, text standardization, inconsistent values fix, date cleaning, data type conversion, outlier handling, aur final clean table creation. Yeh exact same process hai jo real-world data analysts daily follow karte hain. Data Insights SQL Topic Wise series ka pehla topic complete! Aage aur SQL topics aayenge β Window Functions, CTEs, Advanced JOINs aur bahut kuch. Data Insights par sab FREE, detailed, Hinglish mein.
Happy Cleaning & Keep Querying! π
π¬ Comments (0)
Loading comments...