USE tempgb go CREATE TABLE PipeData (id int NOT NULL, ShipName nvarchar(MAX) NOT NULL, ShipAddress nvarchar(MAX) NOT NULL, CONSTRAINT pk_PipeData PRIMARY KEY (id) ) go INSERT PipeData(id, ShipName, ShipAddress) SELECT CustomerID, string_agg(convert(nvarchar(MAX), ShipName), '|') WITHIN GROUP (ORDER BY OrderID), string_agg(convert(nvarchar(MAX), ShipAddress), '|') WITHIN GROUP (ORDER BY OrderID) FROM BigDB..BigOrders GROUP BY CustomerID go ------------------------------------------------- Yithak's XML. -------------------------------------- DROP TABLE IF EXISTS #temp1 DECLARE @d datetime2 = sysdatetime() DECLARE @separator CHAR(1) = '|'; ;WITH rs AS ( SELECT id , TRY_CAST('' + REPLACE(ShipName + @separator + ShipAddress, @separator, '') + '' AS XML).query(' { let $counter := count(/root/r) div 2 for $x in /root/r[position() le $counter] let $pos := count(/root/r[. << $x[1]]) + 1 return } ') AS xmldata FROM PipeData ) SELECT rs.id , n.value('@name','VARCHAR(30)') AS [name] , n.value('@city','VARCHAR(30)') AS [city] INTO #temp1 FROM rs CROSS APPLY xmldata.nodes('/root/r') AS t(n) ORDER BY rs.id; go DROP TABLE IF EXISTS #temp2 ----------------------------------------------------------- Ronen's JSON ------------------------------------------------ DECLARE @d datetime2 = sysdatetime() ;With MyCTE0 as ( select id, ShipName,ShipAddress ,s = '["' + Replace(ShipName, '|', '","') + '"]' ,s1 = '["' + Replace(ShipAddress, '|', '","') + '"]' from PipeData ), MyCTE1 as ( select id, s, s1 , k1 = t.[key], v1 = t.[value] from MyCTE0 CROSS APPLY OPENJSON (s, N'$') t ) SELECT id, v1 , v2 INTO #temp2 FROM MyCTE1 CROSS APPLY (SELECT t1.[key] k2 , t1.[value] v2 FROM OPENJSON (s1, N'$') t1 where t1.[key] = MyCTE1.k1) t SELECT datediff(ms, @d, sysdatetime()) go --------------------------------------------------------------------- My Function ------------------------------ CREATE FUNCTION iter_charlist_to_tbl (@list nvarchar(MAX), @delimiter nchar(1) = N',') RETURNS @tbl TABLE (listpos int IDENTITY(1, 1) NOT NULL, str varchar(4000) NOT NULL, nstr nvarchar(2000) NOT NULL) AS BEGIN DECLARE @endpos int, @startpos int, @textpos int, @chunklen smallint, @tmpstr nvarchar(4000), @leftover nvarchar(4000), @tmpval nvarchar(4000) SET @textpos = 1 SET @leftover = '' WHILE @textpos <= datalength(@list) / 2 BEGIN SET @chunklen = 4000 - datalength(@leftover) / 2 SET @tmpstr = @leftover + substring(@list, @textpos, @chunklen) SET @textpos = @textpos + @chunklen SET @startpos = 0 SET @endpos = charindex(@delimiter COLLATE Slovenian_BIN2, @tmpstr) WHILE @endpos > 0 BEGIN SET @tmpval = ltrim(rtrim(substring(@tmpstr, @startpos + 1, @endpos - @startpos - 1))) INSERT @tbl (str, nstr) VALUES(@tmpval, @tmpval) SET @startpos = @endpos SET @endpos = charindex(@delimiter COLLATE Slovenian_BIN2, @tmpstr, @startpos + 1) END SET @leftover = right(@tmpstr, datalength(@tmpstr) / 2 - @startpos) END INSERT @tbl(str, nstr) VALUES (ltrim(rtrim(@leftover)), ltrim(rtrim(@leftover))) RETURN END go DROP TABLE IF EXISTS #temp3 DECLARE @d datetime2 = sysdatetime() SELECT t.id, s.str + ' ' + s1.str AS ShipStr INTO #temp3 FROM PipeData t CROSS APPLY iter_charlist_to_tbl(t.ShipName, '|') AS s CROSS APPLY iter_charlist_to_tbl(t.ShipAddress, '|') AS s1 WHERE s.listpos = s1.listpos SELECT datediff(ms, @d, sysdatetime()) go -------------------------------------------------------- My temp tables ------------------------------------------ DROP TABLE IF EXISTS #t1 DROP TABLE IF EXISTS #t2 DROP TABLE IF EXISTS #temp4 go DECLARE @d datetime2(3) = sysdatetime() CREATE TABLE #t1 (id int NOT NULL, pos int NOT NULL, ShipName nvarchar(60) NOT NULL, PRIMARY KEY (id, pos)) CREATE TABLE #t2 (id int NOT NULL, pos int NOT NULL, ShipAddress nvarchar(60) NOT NULL, PRIMARY KEY (id, pos)) INSERT #t1(id, pos, ShipName) SELECT t.id, s.listpos, s.nstr FROM PipeData t CROSS APPLY iter_charlist_to_tbl(t.ShipName, '|') AS s INSERT #t2(id, pos, ShipAddress) SELECT t.id, s.listpos, s.nstr FROM PipeData t CROSS APPLY iter_charlist_to_tbl(t.ShipAddress, '|') AS s SELECT t1.id, t1.ShipName + ' ' + t2.ShipAddress as str INTO #temp4 FROM #t1 t1 JOIN #t2 t2 ON t1.id = t2.id AND t1.pos = t2.pos SELECT datediff(ms, @d, sysdatetime())