Menu

How to Use STRING_AGG() for Concatenating Rows into a Single Column in SQL Server

When working with SQL Server, you may encounter scenarios where you need to combine multiple row values into a single column. Prior to SQL Server 2017, this required using STUFF() with FOR XML PATH(), but now, the STRING_AGG() function provides a simpler approach.

What is STRING_AGG()?

The STRING_AGG() function concatenates values from multiple rows into a single string with a specified separator.

Basic Syntax:

SELECT STRING_AGG(column_name, ', ') AS concatenated_values
FROM table_name;
  • column_name: The column whose values you want to concatenate.
  • ', ': The separator used between values.

Example Usage

Consider a Customers table:

id name
1 Alice
2 Bob
3 Charlie

Using STRING_AGG(), we can concatenate the names:

SELECT STRING_AGG(name, ', ') AS customer_names
FROM Customers;

Result:

Alice, Bob, Charlie

Using STRING_AGG() with GROUP BY

You can also use STRING_AGG() within GROUP BY to aggregate data by a specific column. Consider an Orders table:

customer_id product
1 Laptop
1 Mouse
2 Keyboard
2 Monitor

To get a list of products purchased by each customer:

SELECT customer_id, STRING_AGG(product, ', ') AS purchased_products
FROM Orders
GROUP BY customer_id;

Result:

customer_id | purchased_products
------------|-------------------
1           | Laptop, Mouse
2           | Keyboard, Monitor

Sorting Values in STRING_AGG()

By default, STRING_AGG() does not guarantee an order. To enforce ordering, use WITHIN GROUP (ORDER BY column_name). Example:

SELECT STRING_AGG(name, ', ') WITHIN GROUP (ORDER BY name) AS sorted_names
FROM Customers;

Key Benefits of STRING_AGG():

  • Eliminates complex workarounds like STUFF() with FOR XML PATH().
  • More readable and concise syntax.
  • Works efficiently with GROUP BY for aggregating related data.

STRING_AGG() is a powerful function that simplifies string concatenation in SQL Server, making queries cleaner and more efficient. Happy querying!

1
144

Related

When working with SQL Server, you may often need to count the number of unique values in a specific column. This is useful for analyzing data, detecting duplicates, and understanding dataset distributions.

Using COUNT(DISTINCT column_name)

To count the number of unique values in a column, SQL Server provides the COUNT(DISTINCT column_name) function. Here’s a simple example:

SELECT COUNT(DISTINCT column_name) AS distinct_count
FROM table_name;

This query will return the number of unique values in column_name.

Counting Distinct Values Across Multiple Columns

If you need to count distinct combinations of multiple columns, you can use a subquery:

SELECT COUNT(*) AS distinct_count
FROM (SELECT DISTINCT column1, column2 FROM table_name) AS subquery;

This approach ensures that only unique pairs of column1 and column2 are counted.

Why Use COUNT DISTINCT?

  • Helps in identifying unique entries in a dataset.
  • Useful for reporting and analytics.
  • Efficient way to check for duplicates.

By leveraging COUNT(DISTINCT column_name), you can efficiently analyze your database and extract meaningful insights. Happy querying!

1
120

Closing a SqlDataReader correctly prevents memory leaks, connection issues, and unclosed resources. Here’s the best way to do it.

Use 'using' to Auto-Close

Using using statements ensures SqlDataReader and SqlConnection are closed even if an exception occurs.

Example

using (SqlConnection conn = new SqlConnection(connectionString))
{
    conn.Open();
    using (SqlCommand cmd = new SqlCommand("SELECT * FROM Users", conn))
    using (SqlDataReader reader = cmd.ExecuteReader())
    {
        while (reader.Read())
        {
            Console.WriteLine(reader["Username"]);
        }
    } // ✅ Auto-closes reader here
} // ✅ Auto-closes connection here

This approach auto-closes resources when done and it is cleaner and less error-prone than manual closing.

⚡ Alternative: Manually Close in finally Block

If you need explicit control, you can manually close it inside a finally block.

SqlDataReader? reader = null;
try
{
    using SqlConnection conn = new SqlConnection(connectionString);
    conn.Open();
    using SqlCommand cmd = new SqlCommand("SELECT * FROM Users", conn);
    reader = cmd.ExecuteReader();

    while (reader.Read())
    {
        Console.WriteLine(reader["Username"]);
    }
}
finally
{
    reader?.Close();  // ✅ Closes reader if it was opened
}

This is slightly more error prone if you forget to add a finally block. But might make sense when you need to handle the reader separately from the command or connection.

1
182

In C#, you can format an integer with commas (thousands separator) using ToString with a format specifier.

int number = 1234567;
string formattedNumber = number.ToString("N0"); // "1,234,567"
Console.WriteLine(formattedNumber);

Explanation:

"N0": The "N" format specifier stands for Number, and "0" means no decimal places. The output depends on the culture settings, so in regions where , is the decimal separator, you might get 1.234.567.

Alternative:

You can also specify culture explicitly if you need a specific format:

using System.Globalization;

int number = 1234567;
string formattedNumber = number.ToString("N0", CultureInfo.InvariantCulture);
Console.WriteLine(formattedNumber); // "1,234,567"
4
462