我有这样的表
Reg_No Student_Name Subject1 Subject2 Subject3 Subject4 Total
----------- -------------------- ----------- ----------- ----------- ----------- -----------
101 Kevin 85 94 78 90 347
102 Andy 75 88 91 78 332
由此我需要创建一个像这样的临时表或表:
Reg_No Student_Name Subject Total
----------- -------------------- ----------- -----------
101 Kevin 85 347
94
78
90
102 Andy 75 332
88
91
78
我可以在SQL Server
中执行此操作吗?
答案 0 :(得分:5)
<强> DDL:强>
DECLARE @temp TABLE
(
Reg_No INT
, Student_Name VARCHAR(20)
, Subject1 INT
, Subject2 INT
, Subject3 INT
, Subject4 INT
, Total INT
)
INSERT INTO @temp (Reg_No, Student_Name, Subject1, Subject2, Subject3, Subject4, Total)
VALUES
(101, 'Kevin', 85, 94, 78, 90, 347),
(102, 'Andy ', 75, 88, 91, 78, 332)
查询#1 - ROW_NUMBER:
SELECT Reg_No = CASE WHEN rn = 1 THEN t.Reg_No END
, Student_Name = CASE WHEN rn = 1 THEN t.Student_Name END
, t.[Subject]
, Total = CASE WHEN rn = 1 THEN t.Total END
FROM (
SELECT
Reg_No
, Student_Name
, [Subject]
, Total
, rn = ROW_NUMBER() OVER (PARTITION BY Reg_No ORDER BY 1/0)
FROM @temp
UNPIVOT
(
[Subject] FOR tt IN (Subject1, Subject2, Subject3, Subject4)
) unpvt
) t
查询#2 - 外部申请:
SELECT t.*
FROM @temp
OUTER APPLY
(
VALUES
(Reg_No, Student_Name, Subject1, Total),
(NULL, NULL, Subject2, NULL),
(NULL, NULL, Subject3, NULL),
(NULL, NULL, Subject4, NULL)
) t(Reg_No, Student_Name, [Subject], Total)
查询计划:
查询费用:
<强>输出:强>
Reg_No Student_Name Subject Total
----------- -------------------- ----------- -----------
101 Kevin 85 347
NULL NULL 94 NULL
NULL NULL 78 NULL
NULL NULL 90 NULL
102 Andy 75 332
NULL NULL 88 NULL
NULL NULL 91 NULL
NULL NULL 78 NULL
PS:在您的案例中,使用OUTER APPLY
的查询比ROW_NUMBER
解决方案更快。
答案 1 :(得分:4)
最简单的方法是使用UNION
子句
select Reg_No, Student_Name, Subject1, Total from YourTable union all
select Reg_No, Student_Name, Subject2, Total from YourTable union all
select Reg_No, Student_Name, Subject3, Total from YourTable union all
select Reg_No, Student_Name, Subject3, Total from YourTable
将两个或多个查询的结果合并到一个结果集中 包括属于union中所有查询的所有行。 UNION操作与使用组合列的连接不同 从两张桌子。
以下是组合两个结果集的基本规则 使用UNION进行查询:
•列的数量和顺序必须相同 查询。
•数据类型必须兼容。
答案 2 :(得分:2)
;WITH MyCTE AS
(
SELECT *
FROM (
SELECT Reg_No,
[Subject1],
[Subject2],
[Subject3],
[Subject4]
FROM Table1
)p
UNPIVOT
(
Result FOR SubjectName in ([Subject1], [Subject2], [Subject3], [Subject4])
)unpvt
)
SELECT T.Reg_No,
T.Student_Name,
M.SubjectName,
M.Result,
T.Total
FROM Table1 T
JOIN MyCTE M
ON T.Reg_No = M.Reg_No
如果你确实想要其余的NULL值,你可以尝试以下方法:
以下是代码:
;WITH MyCTE AS
(
SELECT *
FROM (
SELECT Reg_No,
[Subject1],
[Subject2],
[Subject3],
[Subject4]
FROM Table1
)p
UNPIVOT
(
Result FOR SubjectName in ([Subject1], [Subject2], [Subject3], [Subject4])
)unpvt
),
MyNumberedCTE AS
(
SELECT *,
ROW_NUMBER() OVER(PARTITION BY Reg_No ORDER BY Reg_No,SubjectName) AS RowNum
FROM MyCTE
)
SELECT T.Reg_No,
T.Student_Name,
M.SubjectName,
M.Result,
T.Total
FROM MyCTE M
LEFT JOIN MyNumberedCTE N
ON N.Reg_No = M.Reg_No
AND N.SubjectName = M.SubjectName
AND N.RowNum=1
LEFT JOIN Table1 T
ON T.Reg_No = N.Reg_No
答案 3 :(得分:0)
答案 4 :(得分:0)
> DECLARE @cols AS NVARCHAR(MAX),@query AS NVARCHAR(MAX)
>
> select @cols = STUFF((SELECT ',' + QUOTENAME(designation)
> from MyTable
> group by designation
> order by designation
> FOR XML PATH(''), TYPE
> ).value('.', 'NVARCHAR(MAX)'),1,1,'')
>
> set @query = N'SELECT Row, ' + @cols + N' from
> (
> select ''SS'' Row, SS AS Value , designation from MyTable
> UNION ALL
> select ''AS'' Row, [AS] AS Value , designation from MyTable
> UNION ALL
> select ''Vac'' Row, Vac AS Value , designation from MyTable
> ) x
> pivot
> (
> max(Value) for designation in (' + @cols + N')
> ) p '
> exec sp_executesql @query;
有关更多详细信息:Convert row into column when number of row is not fixed