返回在列内选择

时间:2012-02-06 15:28:12

标签: sql-server sql-server-2008 tsql

  

可能重复:
  Concatenate column values for rows with the same values (of different columns)

不确定我是否正确地问这个问题,但请在下面查看,以便对我在这里尝试做的事情开玩笑:

SELECT a.ID, (SELECT n.NAME FROM NAMES n WHERE n.ID = a.ID) Names FROM Aliases a

哪个应该返回这样的内容:

 ID          NAMES
 1           Bob, Sally, Jenny

这些不是返回的多行,这是一行返回多个值。这里的关键是将它们返回到一行,而不是多行。有什么建议吗?

3 个答案:

答案 0 :(得分:2)

这可能会有所帮助: 首先是一些测试数据:

DECLARE @tbl TABLE(ID INT, Name VARCHAR(100))
INSERT INTO @tbl
SELECT 1,'Bob' UNION ALL
SELECT 1,'Sally' UNION ALL
SELECT 1,'Jenny'

然后我会做这样的事情:

;WITH CTE AS
(
    SELECT
        tbl.ID
    FROM
        @tbl AS tbl
    GROUP BY
        tbl.ID
) 
SELECT
    CTE.ID,
    STUFF
            (
            (
                SELECT 
                    ',' + Name
                FROM 
                    @tbl AS tbl 
                WHERE 
                    ID = CTE.ID 
                FOR XML PATH('')
            ),1,1,'') AS Names
FROM
    CTE

答案 1 :(得分:0)

最好的方法(如JNK所述)是使用内部联接并将输出分组到应用程序层中。

另一种方法是转动数据,以便得到类似的内容:

ID           Name 1          Name 2            Name 3

1            Bob             Sally             Jenny

这可能很复杂,如果您不知道有多少别名,则需要编写动态数据透视表。

答案 2 :(得分:0)

这可能需要一些改进但肯定会完成工作。我也知道有一种方法可以使用FOR XML PATH('')来实现它,但我不知道如何使用它。

  CREATE TABLE #MyNames 
  ( 
      ID INT, 
      name VARCHAR(MAX) 
  )

declare @Counter1 int
set @Counter1 = 0

declare @Counter2 int
declare @Names varchar(max)

while @Counter1 < select max(Row_Number() Over(Order BY ID)) from Aliases
begin
    set @Counter2 = 0
    set @Names = ''
    while @Counter2 < select max(ID) from Aliases
        begin
            select @Names = COALESCE(@Names + ' ', '') + COALESCE(SELECT ROW_NUMBER() OVER(ORDER BY n.ID) AS 'RowNumb', n.NAME FROM NAMES n WHERE n.ID = Counter1 AND RowNumb = Counter2,'')
            set @Counter2 = Counter2 + 1
        end
    Insert into ##t VALUES(@Counter1,@Names)
set @Counter1 = @Counter1 + 1
end
Select * from #MyNames

虽然这是一个非最佳解决方案,但这样做真的很有意思。