我有一张类似于:
的表格+------+----------+----------+----------+----------+
| Name | Subject1 | Subject2 | Subject3 | Subject4 |
+------+----------+----------+----------+----------+
| x | 10 | 11 | 12 | 13 |
| y | 20 | 21 | 22 | 23 |
| z | 30 | 31 | 32 | 33 |
+------+----------+----------+----------+----------+
我需要得到一个输出:
Name Subject Mark
-------------------------------
x Subject1 10
x Subject2 11
x Subject3 12
x Subject4 13
y Subject1 20
y Subject2 21
y Subject3 22
y Subject4 23
z Subject1 30
z Subject2 31
z Subject3 32
z Subject4 33
我需要一个动态查询,因为数字&列的名称不断从表更改为表。每个表中最少有56列。同样,我有5张桌子。
答案 0 :(得分:1)
将多列转换为多行的过程称为unpivot。如果您有已知值,则可以使用以下内容:
select name, subject, mark
from yourtable
unpivot
(
mark
for subject in (Subject1, Subject2, Subject3, Subject4)
) unpiv;
如果需要动态执行此操作,则将使用动态SQL:
DECLARE @colsUnpivot AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @colsUnpivot
= stuff((select ','+quotename(C.column_name)
from information_schema.columns as C
where C.table_name = 'yourtable' and
C.column_name <> 'Name'
for xml path('')), 1, 1, '')
set @query
= 'select name, subject, mark
from yourtable
unpivot
(
mark
for subject in ('+ @colsunpivot +')
) u'
exec sp_executesql @query;
注意:当您取消数据列的大小时,数据类型必须相同,因此可能需要转换数据。
答案 1 :(得分:1)
它应该是这样的(对代码的评论)。 (Unpivot函数documentation)
--Initialize variables
DECLARE @Columns VARCHAR(MAX) = ''
DECLARE @UnpivotColumns VARCHAR(MAX) = ''
SELECT @Columns = ',' + @Columns FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'your table'
SELECT @UnpivotColumns = ',' + @UnpivotColumns FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'your table' AND COLUMN_NAME LIKE 'Subject%'
--Remove first comma
SET @Columns = STUFF(@Columns,1,1,'')
SET @UnpivotColumns = STUFF(@UnpivotColumns,1,1,'')
--Assemble the dynamic query
DECLARE @qry VARCHAR(Max) = 'SELECT Name, Subject, Mark
FROM
(SELECT ' + @Columns + '
FROM pvt) p
UNPIVOT
(Mark FOR Subject IN
(' + @UnpivotColumns + ')
)AS unpvt;
GO'
--PRINT(@qry)
EXEC (@qry)