2013-12-15 75 views
2

我有以下幾點。TSQL查詢 - 列到行

USE [tempdb] 
GO 

CREATE TABLE #Table (id int, row# int, Info varchar(10), 
         clm11 varchar(10), 
         clm21 varchar(10), 
         clm31 varchar(10), 
         clm41 varchar(10), 
         clm51 varchar(10), 
          clm12 varchar(10), 
          clm22 varchar(10), 
          clm32 varchar(10), 
          clm42 varchar(10), 
          clm52 varchar(10), 
           clm13 varchar(10), 
           clm23 varchar(10), 
           clm33 varchar(10), 
           clm43 varchar(10), 
           clm53 varchar(10)) 
INSERT INTO #Table 
SELECT 1, 100, 'Text', 'Col1', 'Col2', 'Col3', 'Col4', 'Col5','Col11', 'Col12', 'Col13', 'Col14', 'Col15','Col21', 'Col22', 'Col23', 'Col24', 'Col25' 
UNION ALL 
SELECT 2, 100, 'Text', 'Col1', 'Col2', 'Col3', 'Col4', 'Col5', NULL, NULL, NULL, NULL, NULL,'Col21', 'Col22', 'Col23', 'Col24', 'Col25' 
UNION ALL 
SELECT 3, 100, 'Text', 'Col1', 'Col2', 'Col3', 'Col4', 'Col5','Col11', 'Col12', 'Col13', 'Col14', 'Col15', NULL, NULL, NULL, NULL, NULL 
UNION ALL 
SELECT 4, 100, 'Text', 'Col1', 'Col2', 'Col3', 'Col4', 'Col5', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL 
UNION ALL 
SELECT 5, 100, 'Text', NULL, NULL, NULL, NULL, NULL, 'Col11', 'Col12', 'Col13', 'Col14', 'Col15', 'Col21', 'Col22', 'Col23', 'Col24', 'Col25' 
UNION ALL 
SELECT 6, 100, 'Text', NULL, NULL, NULL, NULL, NULL, 'Col11', 'Col12', 'Col13', 'Col14', 'Col15', NULL, NULL, NULL, NULL, NULL 
UNION ALL 
SELECT 7, 100, 'Text', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Col21', 'Col22', 'Col23', 'Col24', 'Col25' 

SELECT * FROM #Table 


/* Desired output 

ID Clm1 Clm2 Clm3 Clm4 Clm5 
1 Col1 Col2 Col3 Col4 Col5 
1 Col11 Col12 Col12 Col14 Col15 
1 Col21 Col22 Col23 Col24 Col25 
2 Col1 Col2 Col3 Col4 Col5 
2 Col21 Col22 Col23 Col24 Col25 
3 Col1 Col2 Col3 Col4 Col5 
3 Col11 Col12 Col13 Col14 Col15 
4 Col1 Col2 Col3 Col4 Col5 
5 Col11 Col12 Col13 Col14 Col15 
5 Col21 Col22 Col23 Col24 Col25 
6 Col11 Col12 Col13 Col14 Col15 
7 Col21 Col22 Col23 Col24 Col25 

*/ 


--- My Try 
SELECT Id, FieldCode, FieldValue 

FROM (SELECT id, clm11, clm21, clm31, clm41, clm51, clm12, clm22, clm32, clm42, clm52, clm13, clm23, clm33, clm43, clm53 FROM #Table) MyTable 

UNPIVOT 
(FieldCode FOR FieldCodes IN (clm11, clm21, clm31, clm41, clm12, clm22, clm32, clm42, clm13, clm23, clm33, clm43))AS CODE 

UNPIVOT 
(FieldValue FOR FieldValues IN (clm51, clm52, clm53))AS FieldValues 
WHERE RIGHT(FieldCodes,1) = RIGHT(FieldValues,1) 


DROP TABLE #Table 

我試圖把ID和Clm11到Clm53(組5列),如果一組(5中校的)有值(非空集),把它們放在一個單獨的記錄ID爲沿如「所需輸出」部分所示。我剛剛顯示了15列(Clm11-Clm51,Clm12-Clm52和Clm13-Clm53),但可以有更多的設置。

請幫忙。

TEMP更新:

select * 
from (select id, 
      (case when n = 1 then clm11 
        when n = 2 then clm21 
        when n = 3 then clm31 
        when n = 4 then clm41 
        when n = 5 then clm51 
       end) as col1, 
       (case when n = 1 then clm12 
        when n = 2 then clm22 
        when n = 3 then clm32 
        when n = 4 then clm42 
        when n = 5 then clm52 
       end) as col2, 
       (case when n = 1 then clm13 
        when n = 2 then clm23 
        when n = 3 then clm33 
        when n = 4 then clm43 
        when n = 5 then clm53 
       end) as col3 
     from #table t cross join 
      (select 1 as n union all select 2 union all select 3 union all select 4 union all select 5) n 
    ) t 
where coalesce(col1, col2, col3) is not null; 

回答

3

我認爲你可以只是由一系列union all做到這一點:

select id, Col11, Col12, Col13, Col14, Col15 
from #table 
where col11 is not null or col12 is not null or col13 is not null or 
     col14 is not null or col15 is not null 
union all 
select id, Col21, Col22, Col23, Col24, Col25 
from #table 
where col21 is not null or col22 is not null or col23 is not null or 
     col24 is not null or col25 is not null 
union all 
select id, Col31, Col32, Col33, Col34, Col35 
from #table 
where col31 is not null or col32 is not null or col33 is not null or 
     col34 is not null or col35 is not null; 

編輯:

是的,有與處理此問題的方法一個表掃描。這個想法是使用一個單獨的櫃檯表和大量的病例陳述。下面是代碼的結構:

select * 
from (select id, 
      (case when n = 1 then col11 
        when n = 2 then col21 
        when n = 3 then col31 
       end) as col1, 
      . . . 
     from #table t cross join 
      (select 1 as n union all select 2 union all select 3) n 
    ) t 
where coalesce(col1, col2, col3, col4, col5) is not null; 

此使用子查詢來定義列,所以where子句不必重複難看case邏輯。

編輯2:

完整的查詢看起來像每次三項條款,而不是三個case語句 case語句:

select * 
from (select id, 
      (case when n = 1 then clm11 
        when n = 2 then clm12 
        when n = 3 then clm13 
       end) as col1, 
       (case when n = 1 then clm21 
        when n = 2 then clm23 
        when n = 3 then clm23 
       end) as col2, 
       (case when n = 1 then clm31 
        when n = 2 then clm32 
        when n = 3 then clm33 
       end) as col3, 
       (case when n = 1 then clm41 
        when n = 2 then clm42 
        when n = 3 then clm43 
       end) as col4, 
       (case when n = 1 then clm51 
        when n = 2 then clm52 
        when n = 3 then clm53 
       end) as col5 
     from t cross join 
      (select 1 as n union all select 2 union all select 3 union all select 4 union all select 5) n 
    ) t 
where coalesce(col1, col2, col3, col4, col5) is not null; 

的SQL小提琴是here

+0

這可以根據需要使用。不過,我相信這個「​​掃描」表至少3次(因爲現在我們有3組5列)。如果我有25組(125列),它將「掃描」表25次?雖然這個sln簡直是美麗而且非常簡單,但是有什麼方法可以使用(un)pivot或者查詢有點小的東西嗎? – 007

+0

查看您的最新方法後,我感到困惑。請查看該操作的TEMP更新部分以查看我正在嘗試的操作...不要以爲我在關注你。 – 007

+0

@ user1569220。 。 。該查詢是我想要避免多個表掃描的。 –