2013-08-30 54 views
6

我有台这样的SQL Server的单行多列合并到一列

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这样做吗?

+3

你是否亲自在你的问题中完成了HTML格式的所有操作?如果你想发表表格数据并保持格式化,你可以突出显示该块并点击'{}'按钮(我承认失败会导致不愿意自己去掉所有格式) –

+0

你在同一组的行中寻找空的空白字段? –

+0

@Damien_The_Unbeliever - 我注意到了。为OP付出努力+1。 –

回答

2

检查this Fiddle

;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值,你可以尝试以下方法:

This is the new Fiddle

这里是代码:

;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 
+0

OP是不是真正想要的。枢纽部分很好,但他也想“清除”所有重复的值。 –

+2

@TimSchmelter,这在任何地方都没有明确提及。这只是暗示的要求的结果... –

+0

@TimSchmelter我编辑了我的答案,并提供了一个额外的解决方案,如果你想检查:) –

3

最简单的方法是使用一个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结果组的两个 查询相结合的基本规则:

•数和列的顺序必须在所有 查询相同。

•数据类型必须兼容。

+0

可能是你想要选择空值而不是reg_no,student_name ...在你得到Subject2,3等的行中 –

+0

@RomanPekar - 如果OP确实需要它,如问题中提供的那样,你是对的,但他怎么样要从该表中选择?还需要一个额外的密钥,以使事情复杂化。 –

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 - OUTER APPLY:

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) 

查询计划:

tt

查询费用:

tt2

输出:

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

+1 SQl-Fiddle:http://sqlfiddle.com/#!6/a6c86/11/0 –

+0

@Tim Schmelter谢谢你的小提琴。 – Devart

+0

+1在外面申请。 –