1

何らかの理由で、次のように値がハードコードされたテーブルがあります。

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 の列と約 12,000 のレコード (約 500,000 の値を意味します) があり、常に追加および修正されています。

これをビューで次のように置き換えようとしています:

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) が得られますが、それを分割して、数字のピリオドと年 (1およびC) を 1 文字で表すにはどうすればよいでしょうか?

文字列を2つの部分に分割するだけで可能かもしれませんが、可能であればよりクリーンな方法を望んでいました.

4

2 に答える 2

2

、、などYPを使用して文字列を簡単に分割できます。私の提案は、. 必要な列がたくさんあるように見えるので、このクエリを実行するために動的 SQL を実装することをお勧めします。次のようにします。LEFT()RIGHT()SUBSTRING()UNPIVOTUNPIVOT

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を参照してください

于 2012-09-24T19:28:36.777 に答える
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
于 2012-09-24T17:30:32.017 に答える