{"id":55244,"date":"2020-01-03T12:33:34","date_gmt":"2020-01-03T12:33:34","guid":{"rendered":"https:\/\/www.sqlshack.com\/?p=55244"},"modified":"2020-01-06T12:17:34","modified_gmt":"2020-01-06T12:17:34","slug":"string_agg-function-in-sql","status":"publish","type":"post","link":"https:\/\/www.sqlshack.com\/string_agg-function-in-sql\/","title":{"rendered":"An overview of the STRING_AGG function in SQL"},"content":{"rendered":"<p>\n    In this article, we will explore the <a\n        href=\"https:\/\/docs.microsoft.com\/en-us\/sql\/t-sql\/functions\/string-agg-transact-sql?view=sql-server-ver15\"\n        target=\"_blank\" rel=\"nofollow\">STRING_AGG<\/a><strong> <\/strong>function in SQL and we will also reinforce our<br \/>\n    learning with various examples.<strong> <\/strong>STRING_AGG<strong> <\/strong>function can be counted as a new member<br \/>\n    of the SQL aggregation functions and it was announced in SQL Server 2017. STRING_AGG function gathers all expression<br \/>\n    from rows and then puts it together in these rows expression in order to obtain a string. Additionally, this<br \/>\n    function takes a separator parameter that allows separating the expressions to be concatenated.\n<\/p>\n<p><!--more--><\/p>\n<h2>How it works<\/h2>\n<p>\n    The following image illustrates the working mechanism of the STRING_AGG function. In this illustration, STRING_AGG<br \/>\n    function takes all rows expression from <strong>Column1<\/strong> and then combines these expressions and it also<br \/>\n    adds the hyphen (<strong>&#8211;<\/strong>) sign as a separator between these expressions. The resulting output of the<br \/>\n    function will be <strong>If-you-want-a-happy-life-save-earth<\/strong>:\n<\/p>\n<p>\n    <a rel=\"lightbox [0]\"\n        href=\"\/wp-content\/uploads\/2020\/01\/the-working-mechanism-of-the-string_agg-function-i01.png\"><img decoding=\"async\"\n            src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2020\/01\/the-working-mechanism-of-the-string_agg-function-i01.png\"\n             alt=\"The working mechanism of the STRING_AGG function in SQL\" \/><noscript><img decoding=\"async\"\n            src=\"\/wp-content\/uploads\/2020\/01\/the-working-mechanism-of-the-string_agg-function-i01.png\"\n             alt=\"The working mechanism of the STRING_AGG function in SQL\" \/><\/noscript><\/a>\n<\/p>\n<h3>STRING_AGG function first example<\/h3>\n<p>\n    Firstly, we will start a pretty simple example of STRING_AGG function and then we will examine the syntax and other<br \/>\n    details about this function. We will create a sample table and populate it with some synthetic data so that we can<br \/>\n    use this table whole examples of the article. The following script will help to generate a sample table called<br \/>\n    <strong>PersonTestTable<\/strong>:\n<\/p>\n<pre lang=\"tsql\">DROP TABLE IF EXISTS [PersonTestTable]\r\nGO\r\nCREATE TABLE [PersonTestTable](\r\n    [FirstName] [varchar](400) NULL,\r\n    [LastName] [varchar](400) NULL,\r\n    [Mail] [varchar](100) NULL,\r\n    Country [varchar](100) NULL,\r\n    Age [int] NULL\r\n    \r\n) ON [PRIMARY]\r\nGO\r\n    \r\nINSERT INTO [dbo].[PersonTestTable]([FirstName],[LastName],[Mail],[Country],[Age]) VALUES (N'Lawrence',N'Williams',N'uhynb.ndlguey@vtq.org',N'U.S.A.',21)\r\nINSERT INTO [dbo].[PersonTestTable]([FirstName],[LastName],[Mail],[Country],[Age]) VALUES (N'Gilbert',N'Miller',N'loiysr.jeoni@wptho.co',N'U.S.A.',53)\r\nINSERT INTO [dbo].[PersonTestTable]([FirstName],[LastName],[Mail],[Country],[Age]) VALUES (N'Salvador',N'Rodriguez',N'tjybsrvg.rswed@uan.org',N'Russia',46)\r\nINSERT INTO [dbo].[PersonTestTable]([FirstName],[LastName],[Mail],[Country],[Age]) VALUES (N'Ernest',N'Jones',N'psxkrzf.jgcmc@pfdknl.org',N'U.S.A.',48)\r\nINSERT INTO [dbo].[PersonTestTable]([FirstName],[LastName],[Mail],[Country],[Age]) VALUES (N'Jerome',N'Garcia',NULL,N'Russia',46)\r\nINSERT INTO [dbo].[PersonTestTable]([FirstName],[LastName],[Mail],[Country],[Age]) VALUES (N'Roland',N'Smith','xpdek.qpl@kpl.com',N'U.S.A. ',35)\r\nINSERT INTO [dbo].[PersonTestTable]([FirstName],[LastName],[Mail],[Country],[Age]) VALUES (N'Stella',N'Johnson',N'qllyoxgr.jsntdty@pzwm.org',N'Russia',24)\r\nINSERT INTO [dbo].[PersonTestTable]([FirstName],[LastName],[Mail],[Country],[Age]) VALUES (N'Aria',N'Anderson',N'sjgnz.voyyc@cvjg.com',N'Brazil ',25)\r\nINSERT INTO [dbo].[PersonTestTable]([FirstName],[LastName],[Mail],[Country],[Age]) VALUES (N'Edward',N'Martinez','pokjs.oas@mex.com',N'Mexico ',27)\r\nINSERT INTO [dbo].[PersonTestTable]([FirstName],[LastName],[Mail],[Country],[Age]) VALUES (N'Nicholas',N'Brown',N'wpfiki.hembt@uww.co',N'Russia ',43)\r\nINSERT INTO [dbo].[PersonTestTable]([FirstName],[LastName],[Mail],[Country],[Age]) VALUES (N'Ray',N'Wilson',NULL,N'Russia',41)\r\nINSERT INTO [dbo].[PersonTestTable]([FirstName],[LastName],[Mail],[Country],[Age]) VALUES (N'Jorge',N'Davis',N'bhlji.zwngl@kle.com',N'Russia ',49)\r\nGO<\/pre>\n<p>\n    In this first example, the STRING_AGG function will take all rows expression from the <strong>FirstName<\/strong><br \/>\n    column of the <strong>PersonTestTable<\/strong> table and then generate a concatenated string with these rows<br \/>\n    expression. At the same time, the concatenated expressions will be separated with the hyphen (<strong>&#8211;<\/strong>)<br \/>\n    sign:\n<\/p>\n<pre lang=\"tsql\">SELECT FirstName FROM PersonTestTable\r\nSELECT STRING_AGG(FirstName,'-') AS Result FROM PersonTestTable<\/pre>\n<p>\n    <img decoding=\"async\" style=\"margin: 0px auto; display: block;\"\n        src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2020\/01\/string_agg-function-example-of-result-illustration.png\"\n         alt=\"STRING_AGG function example of result illustration \" \/><noscript><img decoding=\"async\" style=\"margin: 0px auto; display: block;\"\n        src=\"\/wp-content\/uploads\/2020\/01\/string_agg-function-example-of-result-illustration.png\"\n         alt=\"STRING_AGG function example of result illustration \" \/><\/noscript>\n<\/p>\n<h2>Syntax of STRING_AGG function in SQL<\/h2>\n<p>\n    The syntax of the STRING_AGG function looks like below:\n<\/p>\n<pre lang=\"tsql\">STRING_AGG ( expression, separator ) [ &lt;order_clause&gt; ]<\/pre>\n<p>\n    The <strong>expression<\/strong> parameter specifies any expressions that will be concatenated. The<br \/>\n    <strong>separator<\/strong> parameter is used to separate expressions that will be concatenated. The<br \/>\n    <strong>order_clause<\/strong> parameter is an optional parameter and helps to order the concatenated expression and<br \/>\n    it must be used with WITHIN GROUP statement.\n<\/p>\n<h2>Sorting result of STRING_AGG function in SQL<\/h2>\n<p>\n    STRING_AGG function allows sorting concatenated expressions in descending or ascending order. In this example, we<br \/>\n    will sort the concatenated expressions according to the <strong>FirstName<\/strong> column rows expression with the<br \/>\n    <strong>WITHIN GROUP<\/strong> statement:\n<\/p>\n<p><pre lang=\"tsql\">SELECT FirstName FROM [PersonTestTable] ORDER BY FirstName ASC\r\nGO\r\nSELECT STRING_AGG(FirstName,'-')  WITHIN GROUP ( ORDER BY FirstName ASC)  AS Result FROM [PersonTestTable]<\/pre>\n<\/p>\n<p>\n    <img decoding=\"async\" style=\"margin: 0px auto; display: block;\"\n        src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2020\/01\/string_agg-function-usage-with-within-group-statem.png\"\n         alt=\"STRING_AGG function usage with WITHIN GROUP statement\" \/><noscript><img decoding=\"async\" style=\"margin: 0px auto; display: block;\"\n        src=\"\/wp-content\/uploads\/2020\/01\/string_agg-function-usage-with-within-group-statem.png\"\n         alt=\"STRING_AGG function usage with WITHIN GROUP statement\" \/><\/noscript>\n<\/p>\n<p>\n    As we can see clearly the STRING_AGG function sorted the concatenated expressions in the ascending order according to row values of the FirstName<strong> <\/strong>column. We need to underline one point about this type of usages.<br \/>\n    The<strong> <\/strong>GROUP BY clause will be necessary if the STRING_AGG result is not a sole column in the result<br \/>\n    set of the query. In the next section, we will learn this concept.\n<\/p>\n<h2>How to group concatenated expressions with STRING_AGG<\/h2>\n<p>\n    GROUP BY clause provides grouping the rows that have the same values in SQL Server. In the following example, we<br \/>\n    will generate grouped and concatenated e-mail addresses by the <strong>Country<\/strong> column:\n<\/p>\n<p><pre lang=\"tsql\">SELECT Country,STRING_AGG(Mail,',')  WITHIN GROUP ( ORDER BY FirstName ASC)  AS\r\nResult FROM PersonTestTable\r\nGROUP BY Country\r\nORDER BY Country asc<\/pre>\n<\/p>\n<p>\n    <img decoding=\"async\" style=\"margin: 0px auto; display: block;\"\n        src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2020\/01\/grouping-concatenated-expressions-with-the-string_.png\"\n         alt=\"Grouping concatenated expressions with the STRING_AGG function in SQL\" \/><noscript><img decoding=\"async\" style=\"margin: 0px auto; display: block;\"\n        src=\"\/wp-content\/uploads\/2020\/01\/grouping-concatenated-expressions-with-the-string_.png\"\n         alt=\"Grouping concatenated expressions with the STRING_AGG function in SQL\" \/><\/noscript>\n<\/p>\n<p>\n    At this point, we have to take account of one consideration about the STRING_AGG function. The NULL values are<br \/>\n    ignored when the STRING_AGG concatenates the expressions in the rows and it also does not add an extra separator<br \/>\n    between the expressions due to NULL values. The following example will be illustrated in this case:\n<\/p>\n<p><pre>SELECT Country,Mail\r\nResult FROM [PersonTestTable]\r\nwhere country='Russia' \r\ngroup by Country, Mail\r\n    \r\nSELECT Country,\r\nSTRING_AGG(Mail,',')  WITHIN GROUP ( ORDER BY Mail ASC)  AS\r\nResult FROM [PersonTestTable]\r\nwhere country='Russia' \r\ngroup by Country<\/pre>\n<\/p>\n<p>\n    <img decoding=\"async\" style=\"margin: 0px auto; display: block;\"\n        src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2020\/01\/null-value-and-string_agg-function-interaction.png\"\n        alt=\"NULL value and STRING_AGG function interaction\" \/><noscript><img decoding=\"async\" style=\"margin: 0px auto; display: block;\"\n        src=\"\/wp-content\/uploads\/2020\/01\/null-value-and-string_agg-function-interaction.png\"\n        alt=\"NULL value and STRING_AGG function interaction\" \/><\/noscript>\n<\/p>\n<p>\n    As we can see, the NULL value did not affect the result of the function.\n<\/p>\n<h2>The old method that can be used instead of STRING_AGG function<\/h2>\n<p>\n    If we are using an older version than SQL Server 2017, we can use <strong>FOR<\/strong> <strong>XML PATH<\/strong> and<br \/>\n    <strong>STUFF<\/strong> statements combinations in the query to concatenate rows expressions. However, this method is<br \/>\n    more complicated than STRING_AGG function but it can be useful for the older version of the SQL Server. The<br \/>\n    following query returns the same result as the previous sample:\n<\/p>\n<p><pre lang=\"tsql\">SELECT STUFF((SELECT '-' + FirstName as [text()] FROM PersonTestTable FOR XML PATH('')),1,1,'') AS Result<\/pre>\n<\/p>\n<p>\n    <img decoding=\"async\" style=\"margin: 0px auto; display: block;\"\n        src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2020\/01\/stuff-and-for-xml-path-usage-for-string-concatenat.png\"\n         alt=\"STUFF and FOR XML PATH usage for string concatenation\" \/><noscript><img decoding=\"async\" style=\"margin: 0px auto; display: block;\"\n        src=\"\/wp-content\/uploads\/2020\/01\/stuff-and-for-xml-path-usage-for-string-concatenat.png\"\n         alt=\"STUFF and FOR XML PATH usage for string concatenation\" \/><\/noscript>\n<\/p>\n<p><strong>FOR XML PATH <\/strong>statement provides to generate an <strong>XML<\/strong> element from the query<br \/>\n    result<strong>. <\/strong>When we execute the following query, it transforms query result to XML:\n<\/p>\n<p><pre lang=\"tsql\">SELECT '-' + FirstName as [text()] FROM PersonTestTable FOR XML PATH<\/pre>\n<\/p>\n<p>\n    <a rel=\"lightbox [6]\"\n        href=\"\/wp-content\/uploads\/2020\/01\/for-xml-path-usage-in-sql-server.png\"><img decoding=\"async\"\n            src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2020\/01\/for-xml-path-usage-in-sql-server.png\"\n             alt=\"FOR XML PATH usage in SQL Server\" \/><noscript><img decoding=\"async\"\n            src=\"\/wp-content\/uploads\/2020\/01\/for-xml-path-usage-in-sql-server.png\"\n             alt=\"FOR XML PATH usage in SQL Server\" \/><\/noscript><\/a>\n<\/p>\n<p>\n    If we click the result of the query, we can find out the XML more clearly:\n<\/p>\n<p>\n    <img decoding=\"async\" style=\"margin: 0px auto; display: block;\"\n        src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2020\/01\/output-of-the-for-xml-path.png\" \n        alt=\"Output of the FOR XML PATH \" \/><noscript><img decoding=\"async\" style=\"margin: 0px auto; display: block;\"\n        src=\"\/wp-content\/uploads\/2020\/01\/output-of-the-for-xml-path.png\" \n        alt=\"Output of the FOR XML PATH \" \/><\/noscript>\n<\/p>\n<p>\n    When we add the blank string option at the end of the FOR XML PATH, we will obtain concatenated and separated<br \/>\n    expressions:\n<\/p>\n<p><pre lang=\"tsql\">SELECT '-' + FirstName as [text()] FROM PersonTestTable FOR XML PATH('')<\/pre>\n<\/p>\n<p>\n    <a rel=\"lightbox [8]\"\n        href=\"\/wp-content\/uploads\/2020\/01\/for-xml-path-concanate-the-strings-e1578054700964.png\"><img decoding=\"async\"\n            src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2020\/01\/for-xml-path-concanate-the-strings-e1578054700964.png\"\n             alt=\"FOR XML PATH concanate the strings\" \/><noscript><img decoding=\"async\"\n            src=\"\/wp-content\/uploads\/2020\/01\/for-xml-path-concanate-the-strings-e1578054700964.png\"\n             alt=\"FOR XML PATH concanate the strings\" \/><\/noscript><\/a>\n<\/p>\n<p><a href=\"\/sql-stuff-function-overview\/\"><strong>STUFF<\/strong><\/a> function helps to delete a<br \/>\n    specified part of the string and then it can add a new string to it. Finally, we will clear the first extra<br \/>\n    separator with the STUFF function.\n<\/p>\n<h2>How to generate a concatenated rows in a single cell <\/h2>\n<p>\n    The carriage return allows setting the cursor to the beginning of the next line. We can provide this option in SQL<br \/>\n    with <strong>CHAR(13)<\/strong> statement. We will use CHAR(13) statement as a separator parameter for STRING_AGG<br \/>\n    function so that we can generate concatenated rows into a single cell:\n<\/p>\n<p><pre lang=\"tsql\">SELECT STRING_AGG(FirstName,CHAR(13)) AS Result FROM [PersonTestTable]<\/pre>\n<\/p>\n<p>\n    <img decoding=\"async\" style=\"margin: 0px auto; display: block;\"\n        src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2020\/01\/generating-a-concatenated-row-in-a-single-cell.png\"\n         alt=\"Generating a concatenated row in a single cell \" \/><noscript><img decoding=\"async\" style=\"margin: 0px auto; display: block;\"\n        src=\"\/wp-content\/uploads\/2020\/01\/generating-a-concatenated-row-in-a-single-cell.png\"\n         alt=\"Generating a concatenated row in a single cell \" \/><\/noscript>\n<\/p>\n<p>\n    As we can see, we did not obtain the result that we wished in the SQL Server Management Studio result tab. In fact,<br \/>\n    it misleads us in SSMS because of the query result option. We will change this option in SSMS so that we achieve the<br \/>\n    proper visual. We will find the <strong>Options<\/strong> setting under the <strong>Tools<\/strong> menu and then<br \/>\n    change the <strong>Default destination for result <\/strong>option in the <strong>Query Results<\/strong> setting. We<br \/>\n    will change the <strong>Results to grids<\/strong> option to <strong>Result to text<\/strong>:\n<\/p>\n<p>\n    <img decoding=\"async\" style=\"margin: 0px auto; display: block;\"\n            src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2020\/01\/change-ssms-default-destination-for-result.png\"\n             alt=\"Change SSMS default destination for result\" \/><noscript><img decoding=\"async\" style=\"margin: 0px auto; display: block;\"\n            src=\"\/wp-content\/uploads\/2020\/01\/change-ssms-default-destination-for-result.png\"\n             alt=\"Change SSMS default destination for result\" \/><\/noscript>\n<\/p>\n<p>\n    After this option changing, SSMS shows the result in the text. We will re-execute the same query in a new query<br \/>\n    window:\n<\/p>\n<p><pre lang=\"tsql\">SELECT STRING_AGG(FirstName,CHAR(13)) AS Result FROM PersonTestTable<\/pre>\n<\/p>\n<p>\n    <img decoding=\"async\" style=\"margin: 0px auto; display: block;\"\n        src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2020\/01\/generating-a-concatenated-row-in-a-single-cell-wit.png\"\n         alt=\"Generating a concatenated row in a single cell with STRING_AGG\" \/><noscript><img decoding=\"async\" style=\"margin: 0px auto; display: block;\"\n        src=\"\/wp-content\/uploads\/2020\/01\/generating-a-concatenated-row-in-a-single-cell-wit.png\"\n         alt=\"Generating a concatenated row in a single cell with STRING_AGG\" \/><\/noscript>\n<\/p>\n<h2>How to remove duplicate values in STRING_AGG function<\/h2>\n<p>\n    In some cases, we may need to eliminate duplicate values from the concatenated result of the STRING_AGG function. To<br \/>\n    handle this issue, we can use a two-tier query. In the first <strong>SELECT<\/strong> statement, we will eliminate<br \/>\n    the duplicate rows and then obtain unique values. Then, we will concatenate the unique expression with the<br \/>\n    STRING_AGG function:\n<\/p>\n<p><pre lang=\"tsql\">SELECT STRING_AGG(Cnty, '-')  FROM\r\n(\r\n (SELECT DISTINCT Country AS [Cnty] FROM PersonTestTable)\r\n) AS TMP_TBL<\/pre>\n<\/p>\n<p>\n    <img decoding=\"async\" style=\"margin: 0px auto; display: block;\"\n        src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2020\/01\/eliminating-duplicates-values-in-the-string_agg-fu.png\"\n         alt=\"Eliminating duplicates values in the STRING_AGG Function in SQL\" \/><noscript><img decoding=\"async\" style=\"margin: 0px auto; display: block;\"\n        src=\"\/wp-content\/uploads\/2020\/01\/eliminating-duplicates-values-in-the-string_agg-fu.png\"\n         alt=\"Eliminating duplicates values in the STRING_AGG Function in SQL\" \/><\/noscript>\n<\/p>\n<h2>Advanced details about STRING_AGG function in SQL<\/h2>\n<p>\n    The result type of STRING_AGG is determined according to the first expression that is taken by the function. There<br \/>\n    is no doubt that the <strong>nvarchar<\/strong> and <strong>varchar<\/strong> types concatenated results will be in<br \/>\n    the same type. However, if we concatenate other datatypes which can be converted into string datatypes (int, float,<br \/>\n    datetime and etc.). The result data types will be NVARCHAR(4000) for non-string data types. In the following<br \/>\n    example, we will create a <strong>TempTableForFunction<\/strong> table that has only a float data type column. We<br \/>\n    will try to combine these table expressions through the STRING_AGG function and then the function result will create<br \/>\n    the <strong>TempTableForFunctionResult<\/strong> table.<strong> TempTableForFunctionResult <\/strong>column will be<br \/>\n    generated according to STRING_AGG function result datatype:\n<\/p>\n<pre lang=\"tsql\">DROP TABLE IF EXISTS TempTableForFunction\r\nDROP TABLE IF EXISTS TempTableForFunctionResult\r\nGO\r\n    \r\nCREATE TABLE TempTableForFunction\r\n(SampleVal Float)\r\n    \r\nINSERT INTO TempTableForFunction VALUES (12.67) , (98.09),(65.42),(56.72),(129.12)\r\n    \r\nSELECT STRING_AGG(SampleVal,'-') WITHIN GROUP ( ORDER BY SampleVal ASC) AS Result INTO  TempTableForFunctionResult   FROM TempTableForFunction  \r\n    \r\nSELECT TABLE_SCHEMA,TABLE_NAME,COLUMN_NAME,DATA_TYPE,CHARACTER_MAXIMUM_LENGTH FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='TempTableForFunctionResult'\r\n    \r\nSELECT STRING_AGG(SampleVal,'-') WITHIN GROUP ( ORDER BY SampleVal ASC) AS Result   FROM TempTableForFunction<\/pre>\n<p>\n    Now, examine the result:\n<\/p>\n<p>\n    <img decoding=\"async\" style=\"margin: 0px auto; display: block;\"\n            src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2020\/01\/analyzing-string_agg-function-result-data-type.png\"\n             alt=\"Analyzing STRING_AGG function result data type\" \/><noscript><img decoding=\"async\" style=\"margin: 0px auto; display: block;\"\n            src=\"\/wp-content\/uploads\/2020\/01\/analyzing-string_agg-function-result-data-type.png\"\n             alt=\"Analyzing STRING_AGG function result data type\" \/><\/noscript>\n<\/p>\n<p>\n    The following table shows the STRING_AGG function result types against expression data types:\n<\/p>\n<table>\n<tr>\n<td>\n<p><strong>Input expression type<\/strong>\n            <\/p>\n<\/td>\n<td>\n<p><strong>STRING_AGG function result type<\/strong>\n            <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>\n                NVARCHAR(MAX)\n            <\/p>\n<\/td>\n<td>\n<p>\n                NVARCHAR(MAX)\n            <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>\n                VARCHAR(MAX)\n            <\/p>\n<\/td>\n<td>\n<p>\n                VARCHAR(MAX)\n            <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>\n                NVARCHAR(1&#8230;4000)\n            <\/p>\n<\/td>\n<td>\n<p>\n                NVARCHAR(4000)\n            <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>\n                VARCHAR(1&#8230;8000)\n            <\/p>\n<\/td>\n<td>\n<p>\n                VARCHAR(8000)\n            <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n            <br \/>int, bigint, smallint, tinyint, numeric, float, real, bit, decimal,<\/br><br \/>\n            smallmoney, money, datetime, datetime2,<\/p>\n<\/td>\n<td>\n<p>\n                NVARCHAR(4000)\n            <\/p>\n<\/td>\n<\/tr>\n<\/table>\n<p>\n    At this point, we have to take account of one issue about the STRING_AGG function, it sorted the numbers properly.<br \/>\n    If we look behind at the scene of the query, it means that we will analyze the execution plan of the following query<br \/>\n    with <a href=\"https:\/\/www.apexsql.com\/sql-tools-plan.aspx\">ApexSQL Plan<\/a>:\n<\/p>\n<p><pre lang=\"tsql\">SELECT STRING_AGG(SampleVal,'-') WITHIN GROUP ( ORDER BY SampleVal ASC) AS Result FROM TempTableForFunction<\/pre>\n<\/p>\n<p>\n    <a rel=\"lightbox [14]\"\n        href=\"\/wp-content\/uploads\/2020\/01\/string_agg-function-execution-plan-of-the-query.png\"><img decoding=\"async\"\n            src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2020\/01\/string_agg-function-execution-plan-of-the-query.png\"\n             alt=\"STRING_AGG function execution plan of the query\" \/><noscript><img decoding=\"async\"\n            src=\"\/wp-content\/uploads\/2020\/01\/string_agg-function-execution-plan-of-the-query.png\"\n             alt=\"STRING_AGG function execution plan of the query\" \/><\/noscript><\/a>\n<\/p>\n<p>\n    The sort operation is processed before the Stream Aggregate operation so the numbers are sorted out properly. On the<br \/>\n    other hand, there is a warning sign shown over the SELECT image. If we hover over this image, we can find out more<br \/>\n    details about this issue:\n<\/p>\n<p>\n    <a rel=\"lightbox [15]\" href=\"\/wp-content\/uploads\/2020\/01\/implicit-conversion.png\"><img decoding=\"async\"\n            src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2020\/01\/implicit-conversion.png\" \n            alt=\"Implicit conversion\" \/><noscript><img decoding=\"async\"\n            src=\"\/wp-content\/uploads\/2020\/01\/implicit-conversion.png\" \n            alt=\"Implicit conversion\" \/><\/noscript><\/a>\n<\/p>\n<p>\n    In the above image, the implicit conversion process is shown clearly. Implicit conversion occurs when the SQL Server query execution processes are required to convert one data type to another one and this process is automatically executed during the query execution. In addition, you can look at the <a\n        href=\"\/implicit-conversion-in-sql-server\/\">Implicit conversion in SQL Server<\/a> article<br \/>\n    to learn more details about the implicit conversion notion.\n<\/p>\n<h2>Conclusion<\/h2>\n<p>\n    In this article, we explored the STRING_AGG function in SQL and completed various examples of this function.<br \/>\n    STRING_AGG is a very useful and simple function to convert rows expression into a single string. On the other hand,<br \/>\n    we can use the older version methods to solve these types of issues.\n<\/p>\n<div id=\"see_more\"><\/div>\n<p><script><\/p>\n<p>    display_see_more(text = 'complete', video = 'complete', banner = 'complete', banner_link = 'complete');<\/p>\n<p><\/script><\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>In this article, we will explore the STRING_AGG function in SQL and we will also reinforce our learning with various examples. STRING_AGG function can be counted as a new member of the SQL aggregation functions and it was announced in SQL Server 2017. STRING_AGG function gathers all expression from rows and then puts it together [&hellip;]<!-- AddThis Advanced Settings generic via filter on wp_trim_excerpt --><!-- AddThis Share Buttons generic via filter on wp_trim_excerpt --><\/p>\n","protected":false},"author":102,"featured_media":55267,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[434,25,194],"tags":[],"class_list":["post-55244","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development","category-sql-commands","category-t-sql"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>An overview of the STRING_AGG function in SQL<\/title>\n<meta name=\"description\" content=\"This articles mentions the STRING_AGG function in SQL with examples\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.sqlshack.com\/string_agg-function-in-sql\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"An overview of the STRING_AGG function in SQL\" \/>\n<meta property=\"og:description\" content=\"This articles mentions the STRING_AGG function in SQL with examples\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.sqlshack.com\/string_agg-function-in-sql\/\" \/>\n<meta property=\"og:site_name\" content=\"SQL Shack - articles about database auditing, server performance, data recovery, and more\" \/>\n<meta property=\"article:published_time\" content=\"2020-01-03T12:33:34+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2020-01-06T12:17:34+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.sqlshack.com\/wp-content\/uploads\/2020\/01\/the-working-mechanism-of-the-string_agg-function-i01.png\" \/>\n\t<meta property=\"og:image:width\" content=\"844\" \/>\n\t<meta property=\"og:image:height\" content=\"232\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Esat Erkec\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Esat Erkec\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/string_agg-function-in-sql\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/string_agg-function-in-sql\\\/\"},\"author\":{\"name\":\"Esat Erkec\",\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/#\\\/schema\\\/person\\\/851da6bedf4955fea242eb5238895e01\"},\"headline\":\"An overview of the STRING_AGG function in SQL\",\"datePublished\":\"2020-01-03T12:33:34+00:00\",\"dateModified\":\"2020-01-06T12:17:34+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/string_agg-function-in-sql\\\/\"},\"wordCount\":1330,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/string_agg-function-in-sql\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.sqlshack.com\\\/wp-content\\\/uploads\\\/2020\\\/01\\\/the-working-mechanism-of-the-string_agg-function-i01.png\",\"articleSection\":[\"Development\",\"SQL commands\",\"T-SQL\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/string_agg-function-in-sql\\\/\",\"url\":\"https:\\\/\\\/www.sqlshack.com\\\/string_agg-function-in-sql\\\/\",\"name\":\"An overview of the STRING_AGG function in SQL\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/string_agg-function-in-sql\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/string_agg-function-in-sql\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.sqlshack.com\\\/wp-content\\\/uploads\\\/2020\\\/01\\\/the-working-mechanism-of-the-string_agg-function-i01.png\",\"datePublished\":\"2020-01-03T12:33:34+00:00\",\"dateModified\":\"2020-01-06T12:17:34+00:00\",\"description\":\"This articles mentions the STRING_AGG function in SQL with examples\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.sqlshack.com\\\/string_agg-function-in-sql\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/string_agg-function-in-sql\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.sqlshack.com\\\/wp-content\\\/uploads\\\/2020\\\/01\\\/the-working-mechanism-of-the-string_agg-function-i01.png\",\"contentUrl\":\"https:\\\/\\\/www.sqlshack.com\\\/wp-content\\\/uploads\\\/2020\\\/01\\\/the-working-mechanism-of-the-string_agg-function-i01.png\",\"width\":844,\"height\":232},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/#website\",\"url\":\"https:\\\/\\\/www.sqlshack.com\\\/\",\"name\":\"SQL Shack - articles about database auditing, server performance, data recovery, and more\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.sqlshack.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/#organization\",\"name\":\"SQL Shack\",\"url\":\"https:\\\/\\\/www.sqlshack.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.sqlshack.com\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/sqlshack-default.png\",\"contentUrl\":\"https:\\\/\\\/www.sqlshack.com\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/sqlshack-default.png\",\"width\":1200,\"height\":630,\"caption\":\"SQL Shack\"},\"image\":{\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/#\\\/schema\\\/person\\\/851da6bedf4955fea242eb5238895e01\",\"name\":\"Esat Erkec\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1dd286170fee7101422b45a321bbe7fa7e6c34c6ba57078672f9fbdfa1ebbfa0?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1dd286170fee7101422b45a321bbe7fa7e6c34c6ba57078672f9fbdfa1ebbfa0?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1dd286170fee7101422b45a321bbe7fa7e6c34c6ba57078672f9fbdfa1ebbfa0?s=96&d=mm&r=g\",\"caption\":\"Esat Erkec\"},\"description\":\"Esat Erkec is a SQL Server professional who began his career 8+ years ago as a Software Developer. He is a SQL Server Microsoft Certified Solutions Expert. Most of his career has been focused on SQL Server Database Administration and Development. His current interests are in database administration and Business Intelligence. You can find him on LinkedIn. View all posts by Esat Erkec\",\"url\":\"https:\\\/\\\/www.sqlshack.com\\\/author\\\/esat-erkec\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"An overview of the STRING_AGG function in SQL","description":"This articles mentions the STRING_AGG function in SQL with examples","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.sqlshack.com\/string_agg-function-in-sql\/","og_locale":"en_US","og_type":"article","og_title":"An overview of the STRING_AGG function in SQL","og_description":"This articles mentions the STRING_AGG function in SQL with examples","og_url":"https:\/\/www.sqlshack.com\/string_agg-function-in-sql\/","og_site_name":"SQL Shack - articles about database auditing, server performance, data recovery, and more","article_published_time":"2020-01-03T12:33:34+00:00","article_modified_time":"2020-01-06T12:17:34+00:00","og_image":[{"width":844,"height":232,"url":"https:\/\/www.sqlshack.com\/wp-content\/uploads\/2020\/01\/the-working-mechanism-of-the-string_agg-function-i01.png","type":"image\/png"}],"author":"Esat Erkec","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Esat Erkec","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.sqlshack.com\/string_agg-function-in-sql\/#article","isPartOf":{"@id":"https:\/\/www.sqlshack.com\/string_agg-function-in-sql\/"},"author":{"name":"Esat Erkec","@id":"https:\/\/www.sqlshack.com\/#\/schema\/person\/851da6bedf4955fea242eb5238895e01"},"headline":"An overview of the STRING_AGG function in SQL","datePublished":"2020-01-03T12:33:34+00:00","dateModified":"2020-01-06T12:17:34+00:00","mainEntityOfPage":{"@id":"https:\/\/www.sqlshack.com\/string_agg-function-in-sql\/"},"wordCount":1330,"commentCount":0,"publisher":{"@id":"https:\/\/www.sqlshack.com\/#organization"},"image":{"@id":"https:\/\/www.sqlshack.com\/string_agg-function-in-sql\/#primaryimage"},"thumbnailUrl":"https:\/\/www.sqlshack.com\/wp-content\/uploads\/2020\/01\/the-working-mechanism-of-the-string_agg-function-i01.png","articleSection":["Development","SQL commands","T-SQL"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.sqlshack.com\/string_agg-function-in-sql\/","url":"https:\/\/www.sqlshack.com\/string_agg-function-in-sql\/","name":"An overview of the STRING_AGG function in SQL","isPartOf":{"@id":"https:\/\/www.sqlshack.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.sqlshack.com\/string_agg-function-in-sql\/#primaryimage"},"image":{"@id":"https:\/\/www.sqlshack.com\/string_agg-function-in-sql\/#primaryimage"},"thumbnailUrl":"https:\/\/www.sqlshack.com\/wp-content\/uploads\/2020\/01\/the-working-mechanism-of-the-string_agg-function-i01.png","datePublished":"2020-01-03T12:33:34+00:00","dateModified":"2020-01-06T12:17:34+00:00","description":"This articles mentions the STRING_AGG function in SQL with examples","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.sqlshack.com\/string_agg-function-in-sql\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.sqlshack.com\/string_agg-function-in-sql\/#primaryimage","url":"https:\/\/www.sqlshack.com\/wp-content\/uploads\/2020\/01\/the-working-mechanism-of-the-string_agg-function-i01.png","contentUrl":"https:\/\/www.sqlshack.com\/wp-content\/uploads\/2020\/01\/the-working-mechanism-of-the-string_agg-function-i01.png","width":844,"height":232},{"@type":"WebSite","@id":"https:\/\/www.sqlshack.com\/#website","url":"https:\/\/www.sqlshack.com\/","name":"SQL Shack - articles about database auditing, server performance, data recovery, and more","description":"","publisher":{"@id":"https:\/\/www.sqlshack.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.sqlshack.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.sqlshack.com\/#organization","name":"SQL Shack","url":"https:\/\/www.sqlshack.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.sqlshack.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.sqlshack.com\/wp-content\/uploads\/2019\/03\/sqlshack-default.png","contentUrl":"https:\/\/www.sqlshack.com\/wp-content\/uploads\/2019\/03\/sqlshack-default.png","width":1200,"height":630,"caption":"SQL Shack"},"image":{"@id":"https:\/\/www.sqlshack.com\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.sqlshack.com\/#\/schema\/person\/851da6bedf4955fea242eb5238895e01","name":"Esat Erkec","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/1dd286170fee7101422b45a321bbe7fa7e6c34c6ba57078672f9fbdfa1ebbfa0?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/1dd286170fee7101422b45a321bbe7fa7e6c34c6ba57078672f9fbdfa1ebbfa0?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1dd286170fee7101422b45a321bbe7fa7e6c34c6ba57078672f9fbdfa1ebbfa0?s=96&d=mm&r=g","caption":"Esat Erkec"},"description":"Esat Erkec is a SQL Server professional who began his career 8+ years ago as a Software Developer. He is a SQL Server Microsoft Certified Solutions Expert. Most of his career has been focused on SQL Server Database Administration and Development. His current interests are in database administration and Business Intelligence. You can find him on LinkedIn. View all posts by Esat Erkec","url":"https:\/\/www.sqlshack.com\/author\/esat-erkec\/"}]}},"_links":{"self":[{"href":"https:\/\/www.sqlshack.com\/wp-json\/wp\/v2\/posts\/55244","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.sqlshack.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sqlshack.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sqlshack.com\/wp-json\/wp\/v2\/users\/102"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sqlshack.com\/wp-json\/wp\/v2\/comments?post=55244"}],"version-history":[{"count":11,"href":"https:\/\/www.sqlshack.com\/wp-json\/wp\/v2\/posts\/55244\/revisions"}],"predecessor-version":[{"id":55324,"href":"https:\/\/www.sqlshack.com\/wp-json\/wp\/v2\/posts\/55244\/revisions\/55324"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.sqlshack.com\/wp-json\/wp\/v2\/media\/55267"}],"wp:attachment":[{"href":"https:\/\/www.sqlshack.com\/wp-json\/wp\/v2\/media?parent=55244"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sqlshack.com\/wp-json\/wp\/v2\/categories?post=55244"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sqlshack.com\/wp-json\/wp\/v2\/tags?post=55244"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}