How Do I Concatenate in SQL? A complete walkthrough
Concatenation in SQL is the process of combining two or more strings into a single string. This operation is essential for tasks such as merging first and last names, creating composite keys, or formatting output for reports. Whether you're working with MySQL, SQL Server, PostgreSQL, or Oracle, understanding how to concatenate strings effectively can streamline your data manipulation tasks. This guide will walk you through the different methods, best practices, and common pitfalls of string concatenation in SQL, ensuring you can handle any scenario with confidence Turns out it matters..
Some disagree here. Fair enough.
Introduction to SQL Concatenation
At its core, concatenation is about merging text. And in SQL, this is achieved using built-in functions or operators. Take this: if you have a table of employees with columns first_name and last_name, concatenation allows you to display the full name as a single string. This is particularly useful in generating reports, creating dynamic labels, or preparing data for export to other systems And that's really what it comes down to..
The syntax for concatenation varies slightly between database systems, but the underlying concept remains the same: take multiple strings and join them into one. Below, we’ll explore the most common methods, starting with the basics.
Basic Concatenation Methods
Using the || Operator
The || operator is the most straightforward way to concatenate strings in many SQL dialects, including PostgreSQL, Oracle, and SQLite. It works by placing two or more strings or columns between the operator.
Example:
SELECT first_name || ' ' || last_name AS full_name
FROM employees;
This query combines the first_name, a space, and the last_name into a single full_name column. Even so, note that in SQL Server, this operator is not supported by default, and you’ll need to use the CONCAT() function instead.
Using the CONCAT() Function
The CONCAT() function is widely supported across modern SQL databases, including MySQL, SQL Server, and PostgreSQL. It takes multiple arguments and joins them into a single string.
Example:
SELECT CONCAT(first_name, ' ', last_name) AS full_name
FROM employees;
This produces the same result as the || operator. The CONCAT() function is particularly useful because it handles NULL values gracefully in some databases (more on this later).
Handling NULL Values in Concatenation
Among the challenges with concatenation is dealing with NULL values. Depending on the database system, concatenating a string with NULL can result in NULL, which might not be the desired outcome Practical, not theoretical..
Using CONCAT() with NULL Handling
In MySQL, if any argument to CONCAT() is NULL, the result is NULL. To avoid this, you can use the COALESCE() function to replace NULL with an empty string Worth keeping that in mind..
Example:
SELECT CONCAT(COALESCE(first_name, ''), ' ', COALESCE(last_name, '')) AS full_name
FROM employees;
Using CONCAT_WS() for Separator-Based Concatenation
The CONCAT_WS() function (short for "Concatenate With Separator") is a powerful tool for handling NULL values and adding separators. It automatically ignores NULL values and places the separator between non-null arguments Took long enough..
Example:
SELECT CONCAT_WS(' ', first_name, last_name, department) AS employee_info
FROM employees;
In this case, if department is NULL, it will not add an extra space or separator. This function is available in MySQL, PostgreSQL, and SQL Server (with slight syntax variations).
Concatenating Different Data Types
Concatenation is not limited to strings. You can also combine numeric, date, or other data types by converting them to strings first Most people skip this — try not to..
Converting Numbers to Strings
To concatenate a number with text, use the CAST() or CONVERT() function to convert the number to a string
Converting Dates and Timestamps to Strings
When you need to combine date or timestamp values with other text, most databases provide built‑in functions to format them as strings before concatenation.
| Database | Function | Typical Usage |
|---|---|---|
| PostgreSQL | TO_CHAR(date_col, 'FMDD "of" FMMonth YYYY') |
Returns a formatted textual representation. |
| MySQL | DATE_FORMAT(date_col, '%D %M %Y') |
Similar formatting capabilities. So |
| SQL Server | CONVERT(VARCHAR, date_col, 103) or FORMAT(date_col, 'dd MMMM yyyy') |
Converts to a string using a style code or the newer FORMAT() function. |
| Oracle | TO_CHAR(date_col, 'DD "of" Month YYYY') |
Works like PostgreSQL. |
Example (PostgreSQL)
SELECT first_name || ' joined on ' ||
TO_CHAR(hire_date, 'FMDD "of" FMMonth YYYY') AS intro
FROM employees
WHERE hire_date IS NOT NULL;
Result (sample):
first_name | intro
--------------------------------------------
Alice | Alice joined on 12 of March 2022
Example (SQL Server)
SELECT CONCAT(first_name, ' started ',
CONVERT(VARCHAR, hire_date, 103)) AS intro
FROM employees;
Result (sample):
intro
------------------------------------
Bob started 15 March 2021
Combining Multiple Columns with Conditional Logic
Sometimes you need to concatenate columns only when certain conditions are met, or you want to apply different separators based on the data. The CASE expression combined with CONCAT() (or ||) makes this straightforward.
Example – Include department only if present
SELECT
CONCAT(
first_name,
CASE
WHEN department IS NOT NULL THEN CONCAT(' (', department, ')')
ELSE ''
END
) AS employee_label
FROM employees;
In PostgreSQL you could also write:
SELECT first_name ||
COALESCE((' (' || department || ')')::text, '') AS employee_label
FROM employees;
Performance Tips for Large‑Scale Concatenation
- Avoid unnecessary
COALESCEorCASEinside theSELECTclause when the condition is static; move such logic to an application layer if it will be applied to millions of rows. - Use
CONCAT_WS()(or its equivalent) when a separator is required, because it is optimized to skipNULLvalues and reduces the number of string concatenations internally. - Consider indexing on concatenated expressions only when the result is frequently used in
WHEREorJOINclauses. Some databases (e.g., PostgreSQL) support functional indexes, but creating them on wide concatenations can be storage‑intensive. - Batch processing: If you need to concatenate many columns into a single large string (e.g., for logging), consider using a
STRING_AGG()(SQL Server, PostgreSQL) orGROUP_CONCAT()(MySQL) in a subquery to avoid the overhead of row‑by‑rowCONCAT()calls.
Example – Efficiently aggregating many columns
-- PostgreSQL
SELECT employee_id,
STRING_AGG(column_name, ' | ') AS all_fields
FROM (
SELECT employee_id, 'first_name' AS column_name, first_name AS val FROM employees
UNION ALL
SELECT employee_id, 'last_name', last_name FROM employees
UNION ALL
SELECT employee_id, 'department', department FROM employees
) src
GROUP BY employee_id;
Cross‑Database Cheat Sheet
| Feature | PostgreSQL | MySQL | SQL Server | Oracle |
|---|---|---|---|---|
| String concatenation operator | ` | ` | ` | |
Standard CONCAT() |
CONCAT(str1, str2, …) |
CONCAT(str1, str2, …) |
CONCAT(str1, str2, …) |
CONCAT(str1, str2, …) |
| Separator‑aware concat | CONCAT_WS() (via extension) |
CONCAT_WS() |
STRING_AGG() (newer) or CONCAT_WS() |
LISTAGG() (different syntax) |
| NULL‑tolerant concat | COALESCE(col, '') |
COALESCE(col, '') |
ISNULL(col, '') |
NVL(col, '') |