How should I modify this SQL statement?

2019-06-26 17:53发布

My SQL Server view

SELECT     
   geo.HyperLinks.CatID, geo.Tags.Tag, geo.HyperLinks.HyperLinksID
FROM
   geo.HyperLinks LEFT OUTER JOIN
       geo.Tags INNER JOIN
       geo.TagsList ON geo.Tags.TagID = geo.TagsList.TagID ON geo.HyperLinks.HyperLinksID = geo.TagsList.HyperLinksID WHERE HyperLinksID = 1

returns these...

HyperLinksID CatID Tags
1            2     Sport
1            2     Tennis
1            2     Golf

How should I modify the above to have results like

HyperLinksID CatID TagsInOneRowSeperatedWithSpaceCharacter
1            2     Sport Tennis Golf

UPDATE: As Brad suggested I came up here...

DECLARE @TagList varchar(100)
SELECT @TagList = COALESCE(@TagList + ', ', '') + CAST(TagID AS nvarchar(100))
FROM TagsList
WHERE HyperLinksID = 1
SELECT @TagList

Now the result looks like

HyperLinksID CatID TagsInOneRowSeperatedWithSpaceCharacter
1            2     ID_OF_Sport ID_OF_Tennis ID_OF_Golf

And of course I have to combine the contents from the@TagList variable and the original SELECT statement...

Which means that I'll have to wait for the holy SO bounty :(

3条回答
趁早两清
2楼-- · 2019-06-26 18:20

Using the approach from here to avoid any issues if your tag names contain special XML characters:.

;With HyperLinks As
(
SELECT 1 AS HyperLinksID, 2 AS CatID
),
TagsList AS
(
SELECT 1 AS TagId, 1 AS HyperLinksID UNION ALL
SELECT 2 AS TagId, 1 AS HyperLinksID UNION ALL
SELECT 3 AS TagId, 1 AS HyperLinksID
)
,
Tags AS
(
SELECT 1 AS TagId, 'Sport' as Tag UNION ALL
SELECT 2 AS TagId, 'Tennis' as Tag UNION ALL
SELECT 3 AS TagId, 'Golf' as Tag 
)
SELECT HyperLinksID,
       CatID       ,
      (SELECT mydata
       FROM    ( SELECT Tag AS [data()]
               FROM    Tags t
                       JOIN TagsList tl
                       ON      t.TagId = tl.TagId
               WHERE   tl.HyperLinksID = h.HyperLinksID 
               ORDER BY t.TagId 
               FOR XML PATH(''), TYPE
               ) AS d ( mydata ) FOR XML RAW,
               TYPE
       )
       .value( '/row[1]/mydata[1]', 'varchar(max)' ) TagsInOneRowSeperatedWithSpaceCharacter
FROM   HyperLinks h

Edit: As KM points out in the comments this method actually automatically adds spaces so I've removed the manually added spaces. For delimiters other than spaces such as commas Peter's answer seems more appropriate.

If you know your data will not contain any problematic characters then a simpler (probably more performant) version is

SELECT CatID       ,
       HyperLinksID,
       stuff(
       ( SELECT ' ' + Tag 
               FROM    Tags t
                       JOIN TagsList tl
                       ON      t.TagId = tl.TagId
               WHERE   tl.HyperLinksID = h.HyperLinksID 
               ORDER BY t.TagId 
               FOR XML PATH('')
       ), 1, 1, '') TagsInOneRowSeperatedWithSpaceCharacter
FROM   HyperLinks h
查看更多
Explosion°爆炸
3楼-- · 2019-06-26 18:28

Use FOR XML in a correlated subquery. For a space-delimited list:

SELECT h.HyperLinksID, h.CatID
, TagList = (
    SELECT t.Tag AS [data()]
    FROM geo.TagList l
    JOIN geo.Tags t ON l.TagId = t.TagId
    WHERE l.HyperLinksID = h.HyperLinksID
    ORDER BY t.Tag
    FOR XML PATH(''), TYPE
  ).value('.','NVARCHAR(MAX)')
FROM geo.HyperLinks AS h
WHERE h.HyperLinksID = 1

For any other delimiter:

SELECT h.HyperLinksID, h.CatID
, TagList = STUFF((
      SELECT ', '+t.Tag
      FROM geo.TagList l
      JOIN geo.Tags t ON l.TagId = t.TagId
      WHERE l.HyperLinksID = h.HyperLinksID
      ORDER BY t.Tag
      FOR XML PATH(''), TYPE
    ).value('.','NVARCHAR(MAX)')
  ,1,2,'')
FROM geo.HyperLinks AS h
WHERE h.HyperLinksID = 1

The subquery creates a delimited list, and then STUFF(...,1,2,'') removes the leading ,. TYPE).value() gets around most common problems w/ special characters in XML.

查看更多
戒情不戒烟
4楼-- · 2019-06-26 18:32

If SQL, try this post:

Concatenating Row Values

If you want to try your hand at CLR code, there are examples of creating a custom aggregate function for concatenation, again, for MS SQL.

This post is pretty exhaustive with lots of ways to accomplish your goal.

查看更多
登录 后发表回答