Poiché si utilizza SQL Server, è possibile convertire le righe in colonne in diversi modi. È possibile utilizzare una funzione di aggregazione con un'espressione CASE:
select empid,
max(case when empindex = 1 then empstate end) empState1,
max(case when empindex = 1 then empStDate end) empStDate1,
max(case when empindex = 1 then empEndDate end) empEndDate1,
max(case when empindex = 2 then empstate end) empState2,
max(case when empindex = 2 then empStDate end) empStDate2,
max(case when empindex = 2 then empEndDate end) empEndDate2
from sourcetbl
group by empid;
Vedi SQL Fiddle with Demo.
Se si desidera utilizzare la funzione pivot per ottenere il risultato, allora vi consiglio prima unpivoting le colonne empState
, empStDate
e empEndDate
in modo da avere più righe prima. È possibile utilizzare la funzione UNPIVOT o CROSS Applica per convertire i dati il codice sarà:
select empid, col+cast(empindex as varchar(10)) col, value
from sourcetbl
cross apply
(
select 'empstate', empstate union all
select 'empstdate', convert(varchar(10), empstdate, 120) union all
select 'empenddate', convert(varchar(10), empenddate, 120)
) c (col, value);
Vedi Demo. Una volta che i dati sono pivot, allora si può applicare la funzione pivot in modo che il codice finale sarà:
select empid,
empState1, empStDate1, empEndDate1,
empState2, empStDate2, empEndDate2
from
(
select empid, col+cast(empindex as varchar(10)) col, value
from sourcetbl
cross apply
(
select 'empstate', empstate union all
select 'empstdate', convert(varchar(10), empstdate, 120) union all
select 'empenddate', convert(varchar(10), empenddate, 120)
) c (col, value)
) d
pivot
(
max(value)
for col in (empState1, empStDate1, empEndDate1,
empState2, empStDate2, empEndDate2)
) piv;
Vedi SQL Fiddle with Demo.
Th sopra versioni funzionerà grande se si dispone di un numero limitato di empindex
, ma se poi non è possibile utilizzare SQL dinamico:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(col+cast(empindex as varchar(10)))
from SourceTbl
cross apply
(
select 'empstate', 1 union all
select 'empstdate', 2 union all
select 'empenddate', 3
) c (col, so)
group by col, so, empindex
order by empindex, so
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT empid,' + @cols + '
from
(
select empid, col+cast(empindex as varchar(10)) col, value
from sourcetbl
cross apply
(
select ''empstate'', empstate union all
select ''empstdate'', convert(varchar(10), empstdate, 120) union all
select ''empenddate'', convert(varchar(10), empenddate, 120)
) c (col, value)
) x
pivot
(
max(value)
for col in (' + @cols + ')
) p '
execute sp_executesql @query;
vedere SQL Fiddle with Demo
È possibile utilizzare queste query di INSERT INTO il tuo DestTbl
, o invece di memorizzare i dati in questo formato, ora hai una query per ottenere il risultato desiderato.
Queste query inserire i dati nel formato:
| EMPID | EMPSTATE1 | EMPSTDATE1 | EMPENDDATE1 | EMPSTATE2 | EMPSTDATE2 | EMPENDDATE2 |
---------------------------------------------------------------------------------------
| 10 | AL | 2012-01-01 | 2012-12-01 | FL | 2012-02-01 | 2013-02-01 |
| 15 | FL | 2012-03-20 | 2099-01-01 | (null) | (null) | (null) |
pivot è anche noto come trasformazione in msaccess. la tua domanda è unica in quanto ha anche testo (non numeri interi) nelle celle risultanti. la funzione di aggregazione deve ancora essere applicata, in questo caso MIN() dovrebbe fare bene sui valori di Testo, anche quando c'è solo 1 valore di testo. – hamish