2012-09-24 4 views
1

J'ai une table que pour une raison quelconque a hardcoded valeurs comme ceci:colonnes Transposer aux lignes utilisant 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 

Le tableau a 35 colonnes et autour 12k enregistrements (sens autour 500k valeurs) et est ajouté à et modifié constamment.

Je suis en train de transposer cela dans une vue sur:

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 

Jusqu'à présent, je suis parvenu à le diviser en en valeurs individuelles utilisant cette requête:

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 

Cela me devient un valeur d'identification unique (par exemple, C1), mais comment puis-je la diviser afin d'avoir une période numérique et un seul caractère pour l'année (1 et C)?

Je peux voir qu'il serait peut-être possible de séparer la chaîne en deux parties, mais j'espérais une façon plus propre si possible.

+0

essayez-vous de faire cette dynamique? ou allez-vous coder en dur chaque colonne? – Taryn

Répondre

1

Pourquoi cela semble-t-il sale?

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

C'est beaucoup plus simple que ce que j'essayais, je vais probablement aller de l'avant avec ça! – bendataclear

2

Vous pouvez facilement diviser la chaîne en utilisant YPLEFT(), RIGHT(), SUBSTRING(), etc. Ma suggestion serait de savoir comment vous gérez votre UNPIVOT. Il semble que vous ayez beaucoup de colonnes à UNPIVOT donc ma suggestion pourrait être d'implémenter SQL dynamique pour effectuer cette requête. Vous feriez ainsi:

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) 

voir SQL Fiddle with Demo

+0

Cela semble très utile, mais je préfère éviter SQL dynamique si possible. – bendataclear

+0

@bendataclear Pas de problème, je me suis juste dit que je te montrerais une version dynamique puisque tu avais déclaré que tu avais 35 colonnes. – Taryn

Questions connexes