Afin d'obtenir ce résultat, vous devrez faire quelques petites choses:
- obtenir une liste distincte des valeurs de
col1
et col2
- UNPIVOT les données dans vos colonnes
col1
, col3
et col4
- pivoter le résultat à partir de l'univoque
Pour obtenir la liste distincte des dates et des éléments (col1 et col2) ainsi que les valeurs de votre table existante, vous aurez besoin d'utiliser quelque chose de similaire à ce qui suit:
select t.col1, t.col2,
t2.col3, t2.col4,
row_number() over(partition by t.col2
order by t.col1) seq
from
(
select distinct t.col1, c.col2
from yourtable t
cross join
(
select distinct col2
from yourtable
) c
) t
left join yourtable t2
on t.col1 = t2.col1
and t.col2 = t2.col2;
Voir SQL Fiddle with Demo. Une fois que vous avez cette liste, vous devrez alors déplier les données. Il y a plusieurs façons dont vous pouvez faire cela, en utilisant la fonction UNPIVOT ou en utilisant CROSS APPLY:
select d.col2,
col = col+'_'+cast(seq as varchar(10)),
value
from
(
select t.col1, t.col2,
t2.col3, t2.col4,
row_number() over(partition by t.col2
order by t.col1) seq
from
(
select distinct t.col1, c.col2
from yourtable t
cross join
(
select distinct col2
from yourtable
) c
) t
left join yourtable t2
on t.col1 = t2.col1
and t.col2 = t2.col2
) d
cross apply
(
select 'col1', col1 union all
select 'col3', col3 union all
select 'col4', col4
) c (col, value);
Voir SQL Fiddle with Demo. cela vous donnera des données qui ressemble à:
| COL2 | COL | VALUE |
-------------------------------------------------
| July, 29 2013 00:00:00+0000 | col1_1 | item1 |
| July, 29 2013 00:00:00+0000 | col3_1 | cat |
| July, 29 2013 00:00:00+0000 | col4_1 | blue |
| July, 29 2013 00:00:00+0000 | col1_2 | item2 |
| July, 29 2013 00:00:00+0000 | col3_2 | (null) |
| July, 29 2013 00:00:00+0000 | col4_2 | (null) |
Enfin, vous appliquerez la fonction PIVOT aux éléments dans les colonnes col
:
select col2,
col1_1, col3_1, col4_1,
col1_2, col3_2, col4_2,
col1_3, col3_3, col4_3
from
(
select d.col2,
col = col+'_'+cast(seq as varchar(10)),
value
from
(
select t.col1, t.col2,
t2.col3, t2.col4,
row_number() over(partition by t.col2
order by t.col1) seq
from
(
select distinct t.col1, c.col2
from yourtable t
cross join
(
select distinct col2
from yourtable
) c
) t
left join yourtable t2
on t.col1 = t2.col1
and t.col2 = t2.col2
) d
cross apply
(
select 'col1', col1 union all
select 'col3', col3 union all
select 'col4', col4
) c (col, value)
) src
pivot
(
max(value)
for col in (col1_1, col3_1, col4_1,
col1_2, col3_2, col4_2,
col1_3, col3_3, col4_3)
)piv;
Voir SQL Fiddle with Demo. Si vous avez un nombre inconnu de valeurs, vous pouvez utiliser SQL dynamique pour obtenir le résultat:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(col+'_'+cast(seq as varchar(10)))
from
(
select row_number() over(partition by col2
order by col1) seq
from yourtable
) t
cross apply
(
select 'col1', 1 union all
select 'col3', 2 union all
select 'col4', 3
) c (col, so)
group by col, seq, so
order by seq, so
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT col2, ' + @cols + '
from
(
select d.col2,
col = col+''_''+cast(seq as varchar(10)),
value
from
(
select t.col1, t.col2,
t2.col3, t2.col4,
row_number() over(partition by t.col2
order by t.col1) seq
from
(
select distinct t.col1, c.col2
from yourtable t
cross join
(
select distinct col2
from yourtable
) c
) t
left join yourtable t2
on t.col1 = t2.col1
and t.col2 = t2.col2
) d
cross apply
(
select ''col1'', col1 union all
select ''col3'', col3 union all
select ''col4'', col4
) c (col, value)
) x
pivot
(
max(value)
for col in (' + @cols + ')
) p '
execute sp_executesql @query;
Voir SQL Fiddle with Demo. Toutes les versions donneront un résultat:
| COL2 | COL1_1 | COL3_1 | COL4_1 | COL1_2 | COL3_2 | COL4_2 | COL1_3 | COL3_3 | COL4_3 |
----------------------------------------------------------------------------------------------------------------
| July, 29 2013 00:00:00+0000 | item1 | cat | blue | item2 | (null) | (null) | item3 | fish | purple |
| July, 30 2013 00:00:00+0000 | item1 | rat | green | item2 | bat | grey | item3 | bird | orange |
(Ou mieux si l'itération se joint à elle-même)? – user2044384
Dernier commentaire: le nombre d'éléments peut changer (peut-être ajouter un peu plus - mais le compte n'est pas> 10) - donc une série statique de jointures de la table sur elle-même n'est pas idéale. Merci! – user2044384
Envisagez de gérer les problèmes d'affichage des données dans le code de niveau d'application/couche de présentation si vous en avez un (par exemple en passant un jeu de résultats ordonné à une boucle PHP). C'est beaucoup plus flexible. – Strawberry