ERP Data Migration: SQL Queries You Need for a Smooth Transition
Content
ERP Data Migration: SQL Queries You Need for a Smooth Transition
ERP Data Migration: SQL Queries You Need for a Smooth Transition
ERP Data Migration: SQL Queries You Need for a Smooth Transition
Migrating from one ERP to another is one of the most complex projects a company undertakes. Whether you're moving from on-premise SAP to S/4HANA Cloud, from legacy systems to NetSuite, or from spreadsheets to your first ERP, data migration is where projects succeed or fail.
70% of ERP implementations experience significant delays. The number one cause? Data issues during migration.
These SQL queries help you avoid that fate.
The 4 Phases of ERP Data Migration
Phase
Goal
SQL Role
1. Assessment
Understand source data
Profiling, counting, sampling
2. Cleaning
Fix quality issues
Deduplication, standardization, null handling
3. Transformation
Map to target schema
Data type conversion, field mapping, lookups
4. Validation
Verify completeness
Record counts, checksum comparison, exception reports
Check for nulls, blanks, and invalid data in critical fields:
SELECTCOUNT(*)as total_customers,SUM(CASE WHEN email IS NULL OR email = ''THEN 1ELSE 0END)as missing_email,SUM(CASE WHEN phone IS NULL OR phone = ''THEN 1ELSE 0END)as missing_phone,SUM(CASE WHEN address_line1 IS NULL THEN 1ELSE 0END)as missing_address,SUM(CASE WHEN country IS NULL OR country = ''THEN 1ELSE 0END)as missing_country,SUM(CASE WHEN status NOT IN('ACTIVE','INACTIVE','PROSPECT')THEN 1ELSE 0END)as invalid_status
FROM customers;
Date Range Analysis
Understand what historical data you're migrating:
SELECTMIN(order_date)as earliest_order,MAX(order_date)as latest_order,COUNT(*)as total_orders,COUNT(DISTINCT customer_id)as unique_customers,COUNT(DISTINCT YEAR(order_date))as years_of_data
FROM sales_orders;
Phase 2: Data Cleaning Queries
Find Duplicate Customers
SELECTemail,COUNT(*)as duplicate_count,GROUP_CONCAT(customer_id)as customer_ids,GROUP_CONCAT(customer_name)as names
FROM customersWHERE email IS NOT NULL AND email != ''GROUP BY emailHAVING COUNT(*) > 1ORDER BY duplicate_count DESC;
Standardize Country Codes
SELECT DISTINCT country,COUNT(*)as records
FROM customersWHERE country NOT IN('US','UK','CA','DE','FR','AU','JP')GROUP BY countryORDER BY records DESC;
Clean Phone Number Formats
SELECT customer_id,phone,REGEXP_REPLACE(phone,'[^0-9+]','')as cleaned_phone
FROM customersWHERE phone IS NOT NULLAND phone REGEXP '[^0-9+() -]';
Remove Orphaned Records
-- Order lines without parent ordersSELECT ol.line_id,ol.order_idFROM order_lines olLEFT JOIN sales_orders so ON ol.order_id = so.order_idWHERE so.order_idIS NULL;
-- Invoices without customersSELECT i.invoice_id,i.customer_idFROM ar_invoices iLEFT JOIN customers c ON i.customer_id = c.customer_idWHERE c.customer_idIS NULL;
Phase 3: Data Transformation
Map Account Codes (Old Chart → New Chart)
SELECTold.account_numberas source_account,old.account_nameas source_name,map.new_account_numberas target_account,map.new_account_nameas target_name,COALESCE(map.new_account_number,'UNMAPPED')as mapping_status
FROM gl_accounts oldLEFT JOIN account_mapping map ON old.account_number = map.old_account_numberORDER BY mapping_status DESC,old.account_number;
SELECT'customers'as entity,(SELECT COUNT(*) FROM source_db.customersWHERE status != 'DELETED')as source_count,(SELECT COUNT(*) FROM target_db.customers)as target_count,(SELECT COUNT(*) FROM source_db.customersWHERE status != 'DELETED') -
(SELECT COUNT(*)FROM target_db.customers)as difference;
Financial Balance Verification
-- Source system totalsSELECT'SOURCE'as system,SUM(CASE WHEN entry_type = 'DEBIT'THEN amount ELSE 0END)as total_debits,SUM(CASE WHEN entry_type = 'CREDIT'THEN amount ELSE 0END)as total_credits
FROM source_db.gl_journal_linesUNION ALL
-- Target system totalsSELECT'TARGET',SUM(CASE WHEN entry_type = 'DEBIT'THEN amount ELSE 0END),SUM(CASE WHEN entry_type = 'CREDIT'THEN amount ELSE 0END)FROM target_db.gl_journal_lines;
Find Migration Exceptions
-- Records that existinsource but notintargetSELECT s.customer_id,s.customer_name,s.emailFROM source_db.customerssLEFT JOIN target_db.customerst ON s.customer_id = t.legacy_idWHERE t.legacy_idIS NULLAND s.status != 'DELETED';
Common Migration Pitfalls
Character encoding: Special characters break during transfer. Always check for UTF-8 compatibility
Date formats: MM/DD/YYYY vs DD/MM/YYYY causes silent data corruption
Decimal precision: Financial amounts losing decimal places during conversion
Referential integrity: Foreign keys pointing to records that weren't migrated
Historical data volume: Decide how many years of history to migrate before you start
Let AI Write Your Migration Queries
Migration projects involve hundreds of queries. Data profiling, cleaning, transformation, validation. Each table, each field, each edge case.
AI2SQL accelerates this process. Describe what you need:
"Find all customers with duplicate email addresses"
"Map old account codes to new chart of accounts"
"Compare record counts between source and target databases"
Focus on the migration strategy. Let AI handle the SQL syntax. Try it free at ai2sql.io.