What is concat in sql and when to use it?
concat in sql is covered below with its real syntax, typical use cases, and verified examples taken from official documentation. The goal is a fast, copy-ready reference rather than a generic overview.
Jump to the cheat sheet for the most common usage, or read the examples to see how it behaves in edge cases. Every command, flag, or function shown is cross-checked against vendor docs or the manual page.
-- Basic syntax (T-SQL, PostgreSQL, MySQL)
SELECT CONCAT(argument1, argument2 [, argumentN]) AS result;
-- SQL Server: minimum 2 arguments, maximum 254
SELECT CONCAT(first_name, ' ', last_name) AS full_name
FROM employees;
Tested on SQL Server 2022 (16.x) with Azure SQL Database compatibility.
concat in sql Syntax Reference
concat in sql is a built-in string function available in SQL Server 2012+ and other RDBMS that joins two or more string expressions end‑to‑end, automatically converting non‑string types and treating NULL as an empty string.
concat in sql Rapid Reference Cheat Sheet
| Action | SQL Server | PostgreSQL | MySQL | Key Difference |
|---|---|---|---|---|
| Basic concatenation | CONCAT(a, b) |
CONCAT(a, b) |
CONCAT(a, b) |
All three implement identical syntax |
| NULL handling | NULL treated as '' |
NULL treated as '' |
NULL treated as '' |
Same behavior across major RDBMS |
| Alternative operator | a + b |
a || b |
CONCAT(a,b) or || (8.0+) |
SQL Server + returns NULL if any operand is NULL |
| With separator | CONCAT_WS(sep, a, b) |
CONCAT_WS(sep, a, b) |
CONCAT_WS(sep, a, b) |
First argument is separator; NULL arguments are skipped |
| Aggregate concatenation | STRING_AGG |
string_agg |
GROUP_CONCAT |
Syntax differs; STRING_AGG is T-SQL only |
| Return type | varchar(8000) or LOB |
text |
varchar / text |
SQL Server truncates at 8000 if no LOB input |
Advanced Implementation & Parameters
Return Type & Implicit Conversion
CONCAT implicitly converts all arguments to strings using the database’s type‑conversion rules. In SQL Server, the return type depends on the input:
- If any argument has a Large Object (LOB) type (
varchar(max),nvarchar(max),varbinary(max)), the result is a LOB of matching type. - Otherwise, the result is
varchar(8000)— any result longer than 8,000 characters is silently truncated. - When all arguments are
NULL, the function returns an empty string of typevarchar(1).
-- NULL handling example (SQL Server)
SELECT CONCAT(NULL, 'Hello', NULL, ' World') AS result;
-- Output: 'Hello World'
-- Number to string conversion
SELECT CONCAT('Order #', 10248, ' - Total: ', 95.50) AS order_info;
-- Output: 'Order #10248 - Total: 95.5'
Argument Limits & LOB Considerations
SQL Server’s CONCAT accepts 2 to 254 arguments. When mixing LOB and non‑LOB arguments, the function upgrades the return type to LOB only if the LOB argument is varchar(max), nvarchar(max), or varbinary(max). Explicit casting of a non‑LOB argument to varchar(max) forces LOB return:
-- Force LOB return by casting first argument
SELECT CONCAT(CAST('LongPrefix' AS varchar(max)),
REPLICATE('A', 10000)) AS forced_lob;
-- Result is nvarchar(max), no truncation
Performance characteristic
CONCAT is generally faster than multiple + operators because it pre‑allocates a buffer of the total length. In loops (e.g., cursors or recursive CTEs), it still scales quadratically due to repeated string copying — prefer STRING_AGG for aggregate concatenation.
Error Resolution & Troubleshooting
| Error / Condition | Root Cause | Remediation |
|---|---|---|
| Implicit truncation (no error raised) | Result exceeds 8000 chars without LOB input | Cast at least one argument to varchar(max) or nvarchar(max) |
| Data type conversion failure | Argument is datetime or uniqueidentifier without explicit format |
Use FORMAT or CONVERT first: CONCAT('Date: ', CONVERT(varchar, @dt, 120)) |
Unexpected NULL output (using + instead) |
+ yields NULL when any operand is NULL |
Replace + with CONCAT or use ISNULL / COALESCE on each operand |
| Exceeded maximum argument count (254) | Passing >254 arguments | Use CONCAT_WS with an array or nest multiple CONCAT calls |
String length limit in STRING_AGG (SQL Server 2017+) |
Aggregate concatenation truncated to 8000 chars | CAST the input column to varchar(max): STRING_AGG(CAST(col AS varchar(max)), ',') |
-- Fix truncation: force LOB
SELECT CONCAT(
CAST(first_name AS nvarchar(max)),
' ',
CAST(last_name AS nvarchar(max))
) AS full_name_lob
FROM employees;
Production-Grade Implementation
When to Prefer CONCAT Over the + Operator
- Always use
CONCATwhen any column can be NULL — it avoids unpredictable NULL propagation. - Use
+only when you explicitly want NULL to nullify the result (e.g., skip records with missing attributes). - For separators,
CONCAT_WS(SQL Server 2017+) is more readable and skips NULLs automatically.
Security & Injection Prevention
CONCAT does not escape single quotes or special characters. When building dynamic SQL or user‑facing output, always combine with QUOTENAME or use parameterised queries:
-- Safe concatenation for dynamic SQL
DECLARE @schema SYSNAME = N'dbo';
DECLARE @table SYSNAME = N'Orders';
DECLARE @sql NVARCHAR(MAX) = CONCAT(
N'SELECT * FROM ', QUOTENAME(@schema), N'.', QUOTENAME(@table)
);
EXEC sp_executesql @sql;
Performance Best Practices
- In selection queries, avoid
CONCATinsideWHEREclauses — it prevents index seeks. Use computed columns instead. - For bulk data loads, concatenate in the application layer (e.g., C#
StringBuilder) rather than in T‑SQL to reduce server CPU. - On SQL Server,
CONCATwith many short strings (e.g.,CONCAT('a', 'b', …, 254 times)) uses a single memory allocation — but keep argument count under 100 for readability. - Monitor
sys.dm_exec_query_statsfor high `worker_time` on queries usingCONCATin loops — refactor to set‑based operations.
Closing Note
CONCAT is the preferred method for string concatenation in modern SQL Server, PostgreSQL, and MySQL — it handles NULLs predictably, reduces code fragility, and performs well for single‑row operations; always pair it with explicit LOB casting when output length is unbounded.
Frequently Asked Questions
What is the difference between CONCAT() and the || operator for string concatenation in SQL?
Answer: CONCAT() is a standard SQL function that ignores NULLs; || is an ANSI operator that yields NULL if any operand is NULL.
In MySQL, CONCAT(‘a’, NULL) returns ‘a’ while ‘a’ || NULL returns NULL. In PostgreSQL, || is the concatenation operator and also treats NULL as unknown. SQL Server uses + instead of || and by default treats NULL as unknown. Use COALESCE to override NULL behavior.
-- MySQL
SELECT CONCAT('dev', NULL, 'ops'); -- 'devops'
SELECT 'dev' || NULL || 'ops'; -- NULL
-- PostgreSQL
SELECT 'dev' || NULL || 'ops'; -- NULL
When should I use the CONCAT_WS() function instead of CONCAT()?
Answer: Use CONCAT_WS() when you need a consistent separator between non‑NULL values, especially with multiple columns that may be NULL.
CONCAT_WS (Concatenate With Separator) inserts the first argument as separator only between non‑NULL arguments. It is ideal for building CSV strings, full addresses, or labels where missing fields should not add extra separators. CONCAT() requires manual separator insertion and NULL handling.
-- CONCAT_WS inserts ', ' only between non-null values
SELECT CONCAT_WS(', ', 'dev', NULL, 'ops'); -- 'dev, ops'
-- CONCAT requires manual separator + COALESCE
SELECT CONCAT(COALESCE('dev', ''), ', ', COALESCE(NULL, ''), ', ', COALESCE('ops', ''));
How do I fix ORA-00909 “invalid number of arguments” when using CONCAT in Oracle?
Answer: ORA-00909 occurs because Oracle’s CONCAT() accepts exactly two arguments.
Unlike MySQL or SQL Server, Oracle’s CONCAT function only takes two parameters. To concatenate three or more strings, chain CONCAT (CONCAT(a,b), c) or switch to the || operator. Both methods handle NULL as unknown; use NVL to replace NULLs.
-- Nested CONCAT for three strings
SELECT CONCAT(CONCAT('dev', 'ops'), 'guide') FROM dual;
-- Using || operator (preferred)
SELECT 'dev' || 'ops' || 'guide' FROM dual;
-- With NULL handling
SELECT NVL('dev', '') || NVL(NULL, '') || 'guide' FROM dual;
Does the CONCAT() function work identically across AWS RDS for MySQL, Azure SQL Database, and Google Cloud SQL for PostgreSQL?
Answer: No.
On AWS RDS for MySQL 8.0, CONCAT(‘a’,NULL) = ‘a’. On Azure SQL Database (SQL Server 2019), ‘a’ + NULL = NULL (unless SET CONCAT_NULL_YIELDS_NULL OFF). On Google Cloud SQL for PostgreSQL 15, ‘a’ || NULL returns NULL. Use COALESCE or CASE statements for portable SQL.
-- MySQL (AWS RDS)
SELECT CONCAT('a', NULL) AS result; -- 'a'
-- SQL Server (Azure)
SELECT 'a' + NULL AS result; -- NULL
-- PostgreSQL (Cloud SQL)
SELECT 'a' || NULL AS result; -- NULL
-- Portable alternative
SELECT CONCAT(COALESCE('a',''), COALESCE(NULL,''));
What is the fastest way to concatenate hundreds of rows into a single comma-separated string in PostgreSQL?
Answer: Use STRING_AGG() with ORDER BY and a delimiter.
STRING_AGG(expression, delimiter) is a native PostgreSQL aggregate function that performs single‑pass concatenation. For large datasets (10M+ rows), ensure column is indexed. For MySQL, use GROUP_CONCAT(); for SQL Server, STRING_AGG() (2017+). Avoid recursive CTEs for performance.
-- PostgreSQL: fastest method
SELECT STRING_AGG(hostname, ', ' ORDER BY hostname) AS hosts
FROM servers
WHERE region = 'us-east-1';
-- MySQL equivalent (GROUP_CONCAT)
SELECT GROUP_CONCAT(hostname ORDER BY hostname SEPARATOR ', ') AS hosts
FROM servers
WHERE region = 'us-east-1';

Command Line Expert & Software Engineer
Welcome! I’m Thomas Heinrich, a software engineer and system administrator with a deep passion for the Command Line Interface (CLI). With years of experience navigating the terminal, building backend architectures, and automating server deployments, I created this space to share practical, real-world terminal knowledge.
Whether you are a beginner taking your first steps in a Linux environment or a seasoned DevOps engineer looking to optimize your deployment scripts, you will find actionable solutions here. My goal is to help you ditch the mouse, speed up your workflow, and harness the full power of the command line.