<DataInsights />
  • 🏠 Home
  • πŸ“Š SQL
  • 🐍 Python
  • πŸ“ˆ Power BI
  • πŸ“— Excel
  • πŸ’Ό Career
  • 🎯 Interview Q&A
  • πŸ“ Case Study
  • πŸ“₯ Downloads
  • πŸš€ My Portfolio
<DataInsights />

Practical Data Analytics tutorials covering SQL, Python, Power BI, Excel and career guidance for aspiring analysts β€” 100% free.

Topics

  • SQL Tutorials
  • Python Guide
  • Power BI
  • Excel Tips
  • Career Guide

Quick Links

  • πŸ› οΈ All Tools
  • πŸ—“οΈ Archive
  • πŸ“¬ Contact
  • πŸ” Search
  • Portfolio
  • Kaggle
  • GitHub

Legal & Info

  • About
  • Contact
  • Privacy Policy
  • Disclaimer
  • Terms & Conditions
  • DMCA
  • Sitemap
Copyright © 2026 Data Insights by Jatin Kumar. All Rights Reserved.Built with ❀️ for Data Analysts
Home/SQL/SQL Data Cleaning Techniques β€” 2026 Guide (MySQL)...

SQL Data Cleaning Techniques β€” 2026 Guide (MySQL)

A
August 6, 2026 Jatin Kumar 31 min read SQL
Data Insights SQL Topic Wise

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;

idemp_nameemailgenderdepartmentcitysalaryjoin_datephone
1' Jatin Kumar 'jatin@gmail.comMaleITDelhi500002024-01-159876543210
2'PRIYA PATEL'priya@gmail.comF' Sales 'MUMBAI6000015/03/20249123456780
3'rahul verma'rahul@yahoo.commITdelhi550002024-02-20NULL
4' Neha Gupta'NULLFemaleHRDelhi4800020-Apr-20249988776655
5'Vikram Singh'vikram@gmail.comMALEsalesChennai99999992024-03-109876543210
6' Jatin Kumar 'jatin@gmail.comMaleITDelhi500002024-01-159876543210
7'Sneha Iyer'sneha@outlook.comfemaleMarketingbangalore520002024/05/258877665544
8'Arjun Das'arjun@gmail.comNULL'IT 'Kolkata470002024-06-187766554433
9'Meera Nair'meera@gmail.comFNULLChennai02024-07-016655443322
10'RAHUL VERMA'rahul@yahoo.comMaleITDELHI550002024-02-20NULL

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;
FieldTypeNullKeyDefault
emp_idintYESNULL emp_namevarchar(100)
YESNULL emailvarchar(100)YESNULL gender
varchar(20)YESNULL departmentvarchar(50)YES
NULL cityvarchar(50)YESNULL salaryvarchar(20)
YESNULLvarchar(20)YESNULL

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_namenull_emailnull_gendernull_deptnull_phone
01112

πŸ’» 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 CLEANING
SELECT 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 issues
⚠️ Common Mistake: Cleaning start karna bina explore kiye. Hamesha pehle DESCRIBE + COUNT + DISTINCT run karo β€” pata chal jaayega kya kya clean karna hai. Random cleaning = time waste + miss important issues.

Step 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_idemp_nameemail
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!
⚠️ Common Mistakes:
β€’ 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_nameemailcount
jatin kumarjatin@gmail.com2

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_idemp_nameemailrow_num
1' Jatin Kumar 'jatin@gmail.com1
' Jatin Kumar 'jatin@gmail.com2'rahul verma'
rahul@yahoo.com1'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 βœ…)
⚠️ Common Mistakes:
β€’ 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! πŸŽ‰
⚠️ Common Mistakes:
β€’ 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;
gendercount
Male1
F2
m1
Female1
MALE1
female1
Unknown1
❌7
different values β€” should be only3:

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_idemp_nameold_gendernew_gender
1Jatin kumarMaleMale βœ…
2Priya patelFFemale βœ… (was F)
3Rahul vermamMale βœ… (was m)
4Neha guptaFemaleFemale βœ…
5Vikram singhMALEMale βœ… (was MALE)
7Sneha iyerfemaleFemale βœ… (was female)
8Arjun dasUnknownUnknown βœ…
9Meera nairFFemale βœ… (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: gendercount gendercount
Male1 Male3 βœ… F2 Female4 βœ… m1 Unknown1 βœ… Female1 MALE1 7 groups β†’ 3 groups! Clean! πŸŽ‰ female1 Unknown1

πŸ’» 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 βœ…
⚠️ Common Mistakes:
β€’ 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! πŸŽ‰
⚠️ Common Mistakes:
β€’ 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_idsalary_varcharsalary_intdate_varchardate_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;
FieldTypeBEFORE β†’ AFTER
salaryintvarchar(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;
⚠️ Common Mistakes:
β€’ 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_idemp_namesalarystatus
9Meera nair0ZERO (possibly missing) ⚠️ 8
Arjun das47000NORMAL βœ… 4Neha gupta
48000NORMAL βœ… 1Jatin kumar50000
NORMAL βœ… 7Sneha iyer52000NORMAL βœ… 3
Rahul verma55000NORMAL βœ… 2Priya patel
60000NORMAL βœ… 5Vikram singh9999999

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 βœ…)
⚠️ Common Mistakes:
β€’ 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
⚠️ Common Mistakes:
β€’ 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! πŸš€

πŸ‘€
Jatin Kumar
Data Analyst & Educator

Python, SQL, Power BI aur Excel mein practical tutorials likhta hoon β€” taaki data analytics seekhna aasan ho. Portfolio: jatinanalytics.co.in

Portfolio LinkedIn GitHub Kaggle All Articles
Share:

πŸ’¬ Comments (0)

Spam/links allowed nahi hain β€” respectful comments welcome!

Loading comments...

Was this article helpful?
Previous Article"Database Design β€” ER Diagram, Normalization And Real-World Next Article SQL Window Functions β€” Complete Guide

πŸ“š More Articles Like This

Advanced MySQL β€” Views, Indexes, Stored Procedures, Functions, Triggers And Window Functions

Read Article

"Subqueries β€” Queries ke Andar Queries"

Read Article

SQL JOINS β€” Multiple Tables Ko Connect Karna

Read Article