This is relatively trivial to do with a correlated subquery. You can't use the COALESCE method highlighted in the blog post you mention unless you extract that to a user-defined function (or unless you only want to return one row at a time). Here is how I typically do this:
DECLARE @x TABLE
(
id INT,
row_num INT,
customer_code VARCHAR(32),
comments VARCHAR(32)
);
INSERT @x SELECT 1,1,'Dilbert','Hard'
UNION ALL SELECT 1,2,'Dilbert','Worker'
UNION ALL SELECT 2,1,'Wally','Lazy';
SELECT id, customer_code, comments = STUFF((SELECT ' ' + comments
FROM @x AS x2 WHERE id = x.id
ORDER BY row_num
FOR XML PATH('')), 1, 1, '')
FROM @x AS x
GROUP BY id, customer_code
ORDER BY id;
If you have a case where the data in comments could contain unsafe-for-XML characters (>
, <
, &
), you should change this:
FOR XML PATH('')), 1, 1, '')
To this more elaborate approach:
FOR XML PATH(''), TYPE).value(N'(./text())[1]', N'varchar(max)'), 1, 1, '')
(Be sure to use the right destination data type, varchar
or nvarchar
, and the right length, and prefix all string literals with N
if using nvarchar
.)
You can use the GROUP_CONCAT()
function:
SELECT a.Name AS ArticleName
, GROUP_CONCAT(t.Name) AS TagList
FROM Articles AS a
LEFT JOIN ArticlesTags AS at
ON at.ArticleId = a.Id
LEFT JOIN Tags AS t
ON t.Id = at.TagId
GROUP BY a.Id, a.Name ;
Best Answer
You should be able to use a common table expression along with the ROW_NUMBER and LEAD windowing functions to help with this problem.
By selecting directly from the common table expresssion
SELECT * FROM CTE
you can see that the rn=1 rows are the latest row for each
DIV
. TheLEAD
window function looks to the row just before the latest row for thatDIV
to pick up thesecond_latest_date
.Update: based on your comment about wanting to
union
multiple tables before applying the windowing functions, you could use an inline table expression like this: