2013-08-30 53 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在外面申請。 –