2012-09-24 38 views
1

我有一个表,由于某种原因已经硬编码像这样值的行:移调列使用UNPIVOT

Row ID QtyC1 QtyC2 QtyC3 QtyC4 QtyN1 QtyN2 QtyN3 QtyN4 
100  10  5  8  9  11  12  5  6 
101  9  11  12  5  6  10  4  9 

表有35列和周围12K记录(意为各地500K值)和被添加到并不断修正。

我想在一个视图转成这样:

Row ID Year Period Val 
100  C  1  10 
100  C  2  5 
100  C  3  8 
100  C  4  9 
100  N  1  11 
100  N  2  12 
100  N  3  5 
100  N  4  6 

到目前为止,我已经成功地出来使用此查询拆分成单值:

SELECT Row ID, YP, Val 

FROM (SELECT Row ID 
    , QtyC1 AS C1 
    , QtyC2 AS C2 
    , QtyC3 AS C3 
    , QtyC4 AS C4 
    , QtyN1 AS N1 
    , QtyN2 AS N2 
    , QtyN3 AS N3 
    , QtyN4 AS N4 

FROM MyTable 
) SUB 
UNPIVOT (Val FOR YP IN (C1,C2,C3,C4,N1,N2,N3,N4)) AS PVT 

这让我一个单一识别值(例如C1),但我怎样才能分割它,所以我有一个数字期间和一年的单个字符(1C)?

我可以看到它可能只是将字符串分成两部分,但如果可能的话我希望有一个更清洁的方法。

+0

是你要动态地做到这一点?或者你要硬编码每一列? – Taryn

回答

1

为什么这看起来不洁净?

SELECT Row ID, left(YP, 1) as year, cast(right(yp, 1) as int) as period, Val 
FROM (SELECT Row ID 
    , QtyC1 AS C1 
    , QtyC2 AS C2 
    , QtyC3 AS C3 
    , QtyC4 AS C4 
    , QtyN1 AS N1 
    , QtyN2 AS N2 
    , QtyN3 AS N3 
    , QtyN4 AS N4 
FROM MyTable 
) SUB 
UNPIVOT (Val FOR YP IN (C1,C2,C3,C4,N1,N2,N3,N4)) AS PVT 
+0

这比我想要的要简单得多,我可能会继续这样做! – bendataclear

2

您可以轻松地使用拆分LEFT()RIGHT()SUBSTRING(),等我的建议是,你是如何处理你的UNPIVOTYP字符串。看起来你有很多列到UNPIVOT,所以我的建议可能是实现动态SQL来执行此查询。你会做这种方式:

declare @colsUnpivot varchar(max), 
    @query AS NVARCHAR(MAX), 
    @cols varchar(max) 

select @colsUnpivot = stuff((select ',' 
          +quotename(replace(C.name, 'Qty', '')) 
     from sys.columns as C 
     where C.object_id = object_id('yourtable') and 
       C.name like 'Qty%' 
     for xml path('')), 1, 1, '') 

select @cols = stuff((select ',' 
         +quotename(C.name) + ' as ' + replace(C.name, 'Qty', '') 
     from sys.columns as C 
     where C.object_id = object_id('yourtable') and 
       C.name like 'Qty%' 
     for xml path('')), 1, 1, '') 

set @query 
    = 'select rowid, 
      left(YP, 1) YP, 
      cast(right(YP, len(YP) - 1) as int) period, 
      Val 
    from 
    (
     select rowid, ' + @cols + ' 
     from yourtable 
    ) x1 
    unpivot 
    (
     val for YP IN (' + @colsUnpivot + ') 
    ) u' 

exec(@query) 

看到SQL Fiddle with Demo

+0

这看起来很有用,但我宁愿尽可能避免动态sql。 – bendataclear

+0

@bendataclear没问题,我只是想,我会告诉你一个动态版本,因为你说你有35列。 – Taryn