Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simulating group_concat MySQL function in Microsoft SQL Server 2005?

I'm trying to migrate a MySQL-based app over to Microsoft SQL Server 2005 (not by choice, but that's life).

In the original app, we used almost entirely ANSI-SQL compliant statements, with one significant exception -- we used MySQL's group_concat function fairly frequently.

group_concat, by the way, does this: given a table of, say, employee names and projects...

SELECT empName, projID FROM project_members; 

returns:

ANDY   |  A100 ANDY   |  B391 ANDY   |  X010 TOM    |  A100 TOM    |  A510 

... and here's what you get with group_concat:

SELECT      empName, group_concat(projID SEPARATOR ' / ')  FROM      project_members  GROUP BY      empName; 

returns:

ANDY   |  A100 / B391 / X010 TOM    |  A100 / A510 

So what I'd like to know is: Is it possible to write, say, a user-defined function in SQL Server which emulates the functionality of group_concat?

I have almost no experience using UDFs, stored procedures, or anything like that, just straight-up SQL, so please err on the side of too much explanation :)

like image 402
DanM Avatar asked Jan 16 '09 18:01

DanM


People also ask

Can we use Group_concat in SQL Server?

The SQL Server Equivalent to GROUP_CONCAT() This function allows you to return a result set as a comma-separated list, as opposed to listing each row as a separate row (as with a normal result set).

What does Group_concat do in mysql?

GROUP_CONCAT is a function which concatenates/merges the data from multiple rows into one field. It is a GROUP BY function which returns a string if the group contains at least 1 non-null value, if it does not, it returns a Null value.


1 Answers

No REAL easy way to do this. Lots of ideas out there, though.

Best one I've found:

SELECT table_name, LEFT(column_names , LEN(column_names )-1) AS column_names FROM information_schema.columns AS extern CROSS APPLY (     SELECT column_name + ','     FROM information_schema.columns AS intern     WHERE extern.table_name = intern.table_name     FOR XML PATH('') ) pre_trimmed (column_names) GROUP BY table_name, column_names; 

Or a version that works correctly if the data might contain characters such as <

WITH extern      AS (SELECT DISTINCT table_name          FROM   INFORMATION_SCHEMA.COLUMNS) SELECT table_name,        LEFT(y.column_names, LEN(y.column_names) - 1) AS column_names FROM   extern        CROSS APPLY (SELECT column_name + ','                     FROM   INFORMATION_SCHEMA.COLUMNS AS intern                     WHERE  extern.table_name = intern.table_name                     FOR XML PATH(''), TYPE) x (column_names)        CROSS APPLY (SELECT x.column_names.value('.', 'NVARCHAR(MAX)')) y(column_names)  
like image 98
BradC Avatar answered Oct 14 '22 09:10

BradC