Saturday, 5 February 2011

Aggregate string concatenation

Here's my db diagram:

Now I'm writing a stored procedure to get all the notes for the given user.
No surprises I want CreationDate, Title, NoteText, and Color, but the thing is I also want to get all the tags related to every note.
In my perfectly normalized database tags are stored in a separate table, one record per tag.
But I want all the note tags to be fetched as a single string, separated with spaces.

So, I will use the beautiful and extremely fast technique devised by Michael Rys, a program manager with the Microsoft SQL Server development team, and Eugene Kogan, a technical lead on the Microsoft SQL Server Engine team.


IF OBJECT_ID(N'dbo.GetNotes', N'P') IS NOT NULL
        DROP PROCEDURE dbo.GetNotes;
GO

CREATE PROCEDURE dbo.GetNotes(@UserName NVARCHAR(256))
AS
BEGIN
        SET NOCOUNT ON;

        SELECT
                n.Id
                , n.CreationDate
                , n.Title
                , n.NoteText
                , c.Color
                , LTRIM((                       
                        SELECT
                                ' ' + t.TagText AS [text()]
                        FROM
                                dbo.Tag t
                        JOIN
                                dbo.Note2Tag nt ON t.Id = nt.TagId
                        JOIN
                                dbo.Note n1 ON nt.NoteId = n1.Id
                        WHERE
                                n1.Id = n.Id
                        FOR XML PATH('')
                )) as Tags
        FROM
                dbo.Note n
        JOIN
                dbo.Category c ON n.CategoryId = c.Id
        WHERE
                n.UserName = @UserName
END

No comments:

Post a Comment