2010-06-30 117 views
0

我有一个查询返回一列的结果集,但我希望它被转换成一个长字符串用作子查询。 I.E.我希望能够这样做:Sql select to string

SELECT user.*, (SELECT group_name FROM user_groups WHERE userID = user.ID) AS Groups FROM user 

但是,由于用户可以属于多个组,因此会失败。例如,如果用户属于{"writer", "editor"}我希望它返回像这样的字符串:"writer, editor"

我该怎么做?

回答

1

您可以使用FOR XML来执行此透视操作。这是一个工作示例。

set nocount on 

declare @Users Table 
(
    UserId int, 
    UserName varchar (20) 
) 

declare @UserGroups Table 
(
GroupId int, 
UserId int, 
GroupName varchar (20) 
) 

Insert @Users Values (1, 'Tim') 
Insert @Users Values (2, 'Jane') 
Insert @Users Values (3, 'Hal') 

Insert @UserGroups Values (1, 1, 'Admin') 
Insert @UserGroups Values (2, 1, 'Power-users') 
Insert @UserGroups Values (3, 2, 'Noobs') 
Insert @UserGroups Values (4, 2, 'Users') 
Insert @UserGroups Values (5, 3, 'Noobs') 

/* How this works */ 

SELECT 'FirstStep : Users table' 
SELECT * FROM @Users 

SELECT 'NextStep : User Groups table' 
SELECT * FROM @UserGroups 

SELECT 'NextStep : Users & UserGroups table' 
SELECT * 
FROM @Users U 
    INNER JOIN @UserGroups UG ON U.UserId = UG.UserId 

SELECT 'NextStep : Just get the groups for one user (UserId = 2)' 
SELECT GroupName 
FROM @UserGroups UG 
WHERE UG.userID = 2 
ORDER BY GroupName 

SELECT 'NextStep : When you use XML Path the output comes out in XML format' 
SELECT GroupName 
FROM @UserGroups UG 
WHERE UG.userID = 2 
ORDER BY GroupName 
FOR XML PATH('') -- XML Path added 

SELECT 'NextStep : When you remove the column name the XML tags go away, 
but it looks ugly because there is no separator' 
SELECT GroupName + '' -- Added an empty string to remove the column name 
FROM @UserGroups UG 
WHERE UG.userID = 2 
ORDER BY GroupName 
FOR XML PATH('') 

SELECT 'NextStep : Add a separator 
We add it to the beginning instead of the end so that we can STUFF later on.' 
SELECT ', ' + GroupName -- Added an empty string to remove the column name 
FROM @UserGroups UG 
WHERE UG.userID = 2 
ORDER BY GroupName 
FOR XML PATH('') 

SELECT 'NextStep : I don''t like that ugly XML column name. Let me give it my own name' 
SELECT 
(
    SELECT ', ' + GroupName 
    FROM @UserGroups UG 
    WHERE UG.userID = 2 
    ORDER BY GroupName 
    FOR XML PATH('') 
) as UserGroups 

SELECT 'NextStep : STUFF the extra comma' 
SELECT STUFF 
    (
     (
      SELECT ', ' + GroupName 
      FROM @UserGroups UG 
      WHERE UG.userID = 2 
      ORDER BY GroupName 
      FOR XML PATH('') 
     ), 
     1, 2, '' 
    ) as UserGroups 


SELECT 'NextStep : Now join it with the Users table by the UserId and get the UserName' 
SELECT 
    U.UserName, 
    STUFF 
    (
     (
      SELECT ', ' + GroupName 
      FROM @UserGroups UG 
      WHERE UG.userID = U.userID 
      ORDER BY GroupName 
      FOR XML PATH('') 
     ), 
     1, 2, '' 
    ) as UserGroups 
FROM @Users U 
+0

这是如何工作的? – Malfist 2010-06-30 15:43:20

+0

@Malfist,我加了一步一步解释 – 2010-06-30 16:16:10

+0

好吧,我明白了。因此,如果该列没有名称,则不带路径的FOR XML仅打印出值 – Malfist 2010-06-30 16:37:06