Search code examples
sql-serversubsonic

Get item and all related tags with one query


I have the following tables structure:

Item:

Id,         
Description 

Tags:

Id,
TagName

ItemXrefTag

 Id,
 TagId,
 ItemId

What is the best way to read all the items related to some tag and all other tags, related to the items, to be able to display list of items and all the tags related to the item?

If it's not clear I`ll give the example:

Item, Tags:

 Code complete, book|programming|cool
 Reactoring, book|programming|refactoring|cool
 C# for dummies, book|dont like it| not cool

P.S. I'm using subsonic, but as it support getting data fro mthe query Im ok with the query that will let me get all the data. Sure I can perform join and iterate through multiple lines Ill get and make collection of items with collection of tags for each of it. Im just interested in the most efficient way to implement this.


Solution

  • You are searching for the GROUP_CONCAT function. Just tried it on my database with

    SELECT o.orderno,
           GROUP_CONCAT(d.itemno ORDER BY d.itemno ASC SEPARATOR ', ') as items
    FROM order o
    LEFT JOIN order_detail d ON o.id = d.order_id
    GROUP BY d.order_id
    ORDER BY o.id ASC
    

    returns a result of order numbers with a comma seperated list of ordered items:

    orderno   | items
    ----------------------------------
    201010001 | 100123, 100456, 100987
    201010002 | 123456, 123457
    

    http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat

    But I suppose this is not ANSI SQL so it won't be available for SQL-Server ;-), but a quick search here at stackoverflow returned this question: Simulating group_concat MySQL function in Microsoft SQL Server 2005?

    The corresponding command in sql server should be CROSS APPLY

    Another good article about CROSS APPLY

    http://www.sqlteam.com/article/using-cross-apply-in-sql-server-2005

    For usage with subsonic you should use an InlineQuery (aka CodingHorror) to execute raw sql with subsonic.