不使用数据透视表将行转换为列

时间:2014-05-01 10:00:42

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

如何转换此行:

id id_name flag tag_name tag_type tag_value
1   1       163   XO       c          10
1   1       163   X1       c           0
1   1       163   AM       c           5

这一行:

1   1      163      XO:c:10 X1:c:0 AM:c:5

不使用pivot ??

2 个答案:

答案 0 :(得分:0)

您希望等同于group_concat,而不是pivot

;with src as (select id, id_name, flag, tag_name+':'+tag_type+':'+CONVERT(varchar(5), tag_value) as tag from yourtable t1 )
SELECT distinct
      src.id, src.id_name, src.flag,
      tags = STUFF((
          SELECT ' ' + s.tag
          FROM src s
          WHERE s.id=src.id
          FOR XML PATH(''), TYPE).value('.', 'varchar(max)'), 1, 1, '')
FROM src

答案 1 :(得分:0)

以下是一种可以像您一样的方式来转移数据的方法。通常,最好在应用程序中执行此类字符串构建/操作,而不是直接在数据库上执行。在此示例中,可以将Table2替换为临时表。

-- Create and Seed Table2
SELECT [id], [id_name], [flag], CAST(NULL as varchar(255)) AS [data]
INTO [Table2] FROM [Table1]
GROUP BY [id], [id_name], [flag];

-- Declare variables to hold row
DECLARE @id int, @id_name int, @flag int,
        @tag_name varchar(2), @tag_type varchar(1), @tag_value int;

-- Declare the Cursor
DECLARE PivotCursor CURSOR FOR
    SELECT [id], [id_name], [flag], [tag_name], [tag_type], [tag_value]
    FROM [Table1] ORDER BY [id], [id_name], [flag], [tag_name]
;

-- Use the cursor to update Table2
OPEN PivotCursor;
FETCH NEXT FROM PivotCursor INTO @id, @id_name, @flag, @tag_name, @tag_type, @tag_value;
WHILE @@FETCH_STATUS = 0
BEGIN
    UPDATE Table2 SET
        [Data] = ISNULL([Data],'')+(CASE WHEN [Data] IS NULL THEN '' ELSE ' ' END)+@TagName+':'+@TagType+':'+CAST(@TagValue as varchar)
    WHERE [id] = @id AND [id_name] = @id_name AND [flag] = @flag;

    -- Get Next
    FETCH NEXT FROM PivotCursor INTO @id, @id_name, @flag, @tag_name, @tag_type, @tag_value;
END
CLOSE PivotCursor;
DEALLOCATE PivotCursor;

结果表如下所示:

id  id_name  flag   data
1   1        163    AM:c:5 X1:c:0 XO:c:10