我有一个包含四列item_id,颜色,大小,重量的表,我想将我的表行显示为一行,如item1,color1,size1,weight1,item2,color2,......... ..,item4,color4,size4,weight4 ......
以下是我的表
+---------+--------+--------+--------+
| item_id | color | size | weight |
+---------+--------+--------+--------+
| 1 | blue | large | 65 |
| 2 | orange | large | 57 |
| 3 | red | small | 12 |
| 4 | violet | medium | 34 |
我想要的结果将是
+---------+--------+--------+--------++---------+--------+--------+
| item_id1| color1| size1 | weight1| item_id2 | color2 | size2 | weight2 |....
+---------+--------+--------+--------+---------+--------+--------+---------------
| 1 | blue | large| 65 | 2 | orange | large | 57 |...
+---------+--------+--------+--------+ +---------+--------+--------+--------+
提前致谢。
答案 0 :(得分:3)
为了得到这个结果,你需要做一些事情:
由于您使用的是SQL Server 2005+,因此可以使用CROSS APPLY来取消数据的移动,此过程将使用item_id
,color
,size
和{{1}的多列并将它们转换为多行:
weight
见SQL Fiddle with Demo。这给出了一个结果:
select col+'_'+cast(seq as varchar(50)) col,
value
from
(
select item_id as seq, item_id, color, size, weight
from yourtable
) d
cross apply
(
values
('item_id', cast(item_id as varchar(50))),
('color', color),
('size', size),
('weight', cast(weight as varchar(50)))
) c (col, value);
从结果中可以看出,您现在有多个基于原始数据的行。 | COL | VALUE |
----------------------
| item_id_1 | 1 |
| color_1 | blue |
| size_1 | large |
| weight_1 | 65 |
| item_id_2 | 2 |
| color_2 | orange |
| size_2 | large |
| weight_2 | 57 |
| item_id_3 | 3 |
值是您将用于PIVOT的值。完整的动态SQL代码将类似于以下内容:
COL
见SQL Fiddle with Demo。最终结果是:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(col+'_'+cast(item_id as varchar(10)))
from yourtable
cross apply
(
select 'item_id', 0 union all
select 'color', 1 union all
select 'size', 2 union all
select 'weight', 3
) c (col, so)
group by item_id, col, so
order by item_id, so
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT ' + @cols + '
from
(
select col+''_''+cast(seq as varchar(50)) col,
value
from
(
select item_id as seq, item_id, color, size, weight
from yourtable
) d
cross apply
(
values
(''item_id'', cast(item_id as varchar(50))),
(''color'', color),
(''size'', size),
(''weight'', cast(weight as varchar(50)))
) c (col, value)
) x
pivot
(
max(value)
for col in (' + @cols + ')
) p '
execute(@query);
答案 1 :(得分:2)
如果您想以编程方式执行此操作并且您不知道行数,请尝试以下操作:
DECLARE @I INT, @END INT, @DATA nvarchar(max), @TEMPSTR nvarchar(max), @DynamicTableSQL nvarchar(max)
SET @I = 1
SET @DATA = ''
SET @TEMPSTR = ''
SELECT @END = MAX(item_id) from items
SET @DynamicTableSQL = 'DECLARE @DynamicTable TABLE('
WHILE @I <= @END
BEGIN
--SELECT @I
SET @TEMPSTR = (select CAST(item_id as nvarchar) + ',''' + color + ''',''' + size + ''',' + cast(weight as nvarchar) + ',' FROM items WHERE item_id = @I)
SET @DynamicTableSQL = @DynamicTableSQL + 'item_id_' + CAST(@I AS VARCHAR(10))+ ' INT ,' + 'color_' + CAST(@I AS VARCHAR(10))+ ' NVARCHAR(15) ,'+ 'size_' + CAST(@I AS VARCHAR(10))+ ' NVARCHAR(15) ,'+ 'weight_' + CAST(@I AS VARCHAR(10))+ ' INT ,'
SET @DATA += @TEMPSTR
SELECT @I = @I + 1
END
SET @DynamicTableSQL = SUBSTRING(@DynamicTableSQL, 0, LEN(@DynamicTableSQL))
SET @DynamicTableSQL = @DynamicTableSQL + ') '
SET @DATA = SUBSTRING(@DATA, 0, LEN(@DATA))
SET @DynamicTableSQL = @DynamicTableSQL + ' INSERT INTO @DynamicTable VALUES (' + @DATA + ')'
SET @DynamicTableSQL = @DynamicTableSQL + ' SELECT * FROM @DynamicTable '
EXEC SP_EXECUTESQL @DynamicTableSQL