web-dev-qa-db-fra.com

essayer d'aplatir les lignes en colonnes

J'ai un groupe de lignes dans une table qui ont un identifiant. J'essaie de l'aplatir en rangées avec plusieurs colonnes. Je suis presque certain d'avoir fait cela avec un cte et peut-être une partition.

J'ai utilisé des cte pour supprimer les données en double et je pensais avoir fait quelque chose de similaire à ce que j'essaie d'accomplir ici. J'ai pu trouver une solution réalisable (répertoriée ci-dessous) mais je pense toujours qu'une solution plus élégante devrait être disponible.

CREATE TABLE #MyTable ( RowID int , field VARCHAR(10), value  VARCHAR(10))  

INSERT INTO #MyTable ( RowID, field, value ) VALUES  ( 1, 'first', 'neil' )

INSERT INTO #MyTable ( RowID, field, value ) VALUES  ( 2, 'first', 'bob'  )

INSERT INTO #MyTable ( RowID, field, value ) VALUES  ( 3, 'first', 'tom'  )

INSERT INTO #MyTable ( RowID, field, value ) VALUES  ( 1, 'last', 'young' )

INSERT INTO #MyTable ( RowID, field, value ) VALUES  ( 2, 'last', 'dylan' )

INSERT INTO #MyTable ( RowID, field, value ) VALUES  ( 3, 'last', 'petty' )

SELECT * FROM #mytable

- essayer d'accomplir cela avec cte/partition:

SELECT rowid, 
   [first] = (Select value FROM #mytable where field = 'first' and rowid = t.rowid), 
   [last] = (Select value FROM #mytable where field = 'last' and rowid = t.rowid)
FROM #mytable t
GROUP BY rowid
20
boone

Cette transformation de données est connue sous le nom de PIVOT . Dans SQL Server 2005+, il existe une fonction qui exécutera ce processus. :

select *
from
(
  SELECT * 
  FROM mytable
) src
pivot
(
  max(value)
  for field in (first, last)
) piv

Voir SQL Fiddle with Demo .

Ou vous pouvez utiliser une fonction d'agrégation avec une expression CASE:

select rowid,
  max(case when field = 'first' then value end) first,
  max(case when field = 'last' then value end) last
from MyTable
group by rowid

Voir SQL Fiddle with Demo .

Vous pouvez également utiliser plusieurs jointures sur votre table:

select t1.rowid,
  t1.value first,
  t2.value last
from mytable t1
left join mytable t2
  on t1.rowid = t2.rowid
  and t2.field = 'last'
where t1.field = 'first'

Voir SQL Fiddle with Demo

Le résultat pour toutes les versions est le même:

| ROWID | FIRST |  LAST |
-------------------------
|     1 |  neil | young |
|     2 |   bob | dylan |
|     3 |   tom | petty |
28
Taryn