SQL-Engineering-Handbook

03 — String Transformation

🏠 Module Home · 🗂️ Handbook Home · ← 02 String Search & Extraction · Next → 04 String Cleaning & Validation

String Transformation

Introduction

Search and extraction (Topic 02) answer “where is it” and “give me a piece.” Transformation functions answer “change it” — replace one substring with another, reverse a sequence for a checksum algorithm, pad a value to a fixed width for a legacy fixed-length export, or repeat a character to build a formatted separator line. This topic uses a banking/finance schema — account numbers, transaction references, and report formatting — where fixed-width formatting requirements are common and non-negotiable.

Concept Overview

Transformation functions modify a string’s content or shape without needing to first locate anything within it:

  1. Content replacementREPLACE()
  2. Sequence manipulationREVERSE(), REPEAT(), SPACE()
  3. Positional insertionINSERT()
  4. Fixed-width formattingLPAD(), RPAD()

Business Motivation

Legacy financial systems, regulatory reporting formats, and fixed-width file interchange (still common in banking, insurance, and government systems) require exact character-width output — an account number padded to 12 digits with leading zeros, an amount field padded to a fixed width for a mainframe-compatible export. Transformation functions are how SQL meets these formatting contracts without post-processing in another language.

Why These Functions Exist

Many downstream systems — especially older or regulatory ones — were not designed around variable-length text; they expect exact-width fields at fixed byte offsets. Padding and replacement functions exist to bridge modern variable-length relational storage with these fixed-width contracts, and to perform bulk content standardization (masking, format normalization) directly in the query layer.

Real Company Use Cases

Functions Covered

Function Purpose
REPLACE() Replaces all occurrences of a substring with another
REVERSE() Reverses the character order of a string
REPEAT() Repeats a string a specified number of times
SPACE() Returns a string of N spaces
INSERT() Inserts a substring at a given position, replacing a given length
LPAD() Pads a string on the left to a target length
RPAD() Pads a string on the right to a target length

Syntax

REPLACE(str, from_str, to_str)
REVERSE(str)
REPEAT(str, count)
SPACE(count)
INSERT(str, start_pos, length, new_str)
LPAD(str, target_length, pad_str)
RPAD(str, target_length, pad_str)

Parameters

Return Values

All functions in this family return a string, or NULL if any argument is NULL. LPAD/RPAD with a target_length shorter than the input’s current length return a truncated string in most engines — this is a common source of silent data loss and is called out explicitly in Edge Cases.

ASCII Visual Explanation

account_number = "48213"

LPAD(account_number, 10, '0')
    →  "0000048213"
        ^^^^^^ zero-padding added on the LEFT to reach length 10

RPAD(account_number, 10, '*')
    →  "48213*****"
             ^^^^^ padding added on the RIGHT to reach length 10

Step-by-Step Examples

Goal: Format account numbers to a fixed 10-digit width for a regulatory export, zero-padded on the left.

SELECT
    account_number,
    LPAD(account_number, 10, '0') AS export_account_number
FROM accounts;

Reasoning: Regulatory file specifications commonly require fixed-width numeric fields; LPAD() with '0' matches the conventional zero-padding used for numeric identifiers, as opposed to RPAD(), which would be used for left-aligned text fields.

Production Considerations

Performance Notes

Edge Cases

Common Mistakes

Best Practices

Interview Questions

  1. What happens when LPAD()’s target length is shorter than the input string’s actual length?
  2. How would you mask a customer’s account number to show only the last 4 digits, using string functions?
  3. REPLACE('aabbaa', 'a', 'X') — what’s the result, and why might that surprise someone expecting only the first match to be replaced?
  4. When would you use INSERT() instead of a combination of LEFT(), RIGHT(), and CONCAT()?

Practice Challenges

  1. Write a query that masks each account_number, showing only the last 4 digits and replacing the rest with *, regardless of the account number’s length.
  2. Format transaction_ref values to a fixed 15-character width, right-padded with spaces, for a legacy fixed-width export.
  3. Using REPLACE(), normalize a raw_phone column that inconsistently uses both - and . as separators into a single consistent - separator.

Summary

Transformation functions reshape string content and width to satisfy formatting contracts that relational storage doesn’t enforce on its own — fixed-width exports, masked display values, and normalized delimiters. The recurring risk across this family is silent truncation and unintended multi-match replacement; both are cheap to guard against once you know to look for them.

Further Reading


⬆ Back to top · 🏠 Module Home · 🗂️ Handbook Home