Da Sie SQL Server verwenden, gibt es verschiedene Möglichkeiten, die Zeilen in Spalten umzuwandeln. Sie können eine Aggregatfunktion mit einem CASE-Ausdruck verwenden:
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;
Siehe SQL Fiddle with Demo.
Wenn Sie die Pivot-Funktion erhalten Sie das Ergebnis verwenden wollen, dann würde ich empfehlen, zuerst unpivoting die Spalten empState
, empStDate
und empEndDate
so werden Sie zunächst mehrere Zeilen haben. Sie können die UNPIVOT Funktion oder CROSS APPLY verwenden, um die Daten zu konvertieren wird der Code sein:
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);
Siehe Demo. Sobald die Daten nicht verschwenkten ist, dann können Sie die Pivot-Funktion anwenden, so wird der endgültige Code sein:
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;
SQL Fiddle with Demo See.
Th oben genannten Versionen wird groß, wenn Sie eine begrenzte Anzahl von empindex
haben, aber wenn nicht, dann können Sie die dynamische SQL verwenden:
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;
Siehe SQL Fiddle with Demo
Sie können diese Abfragen verwenden, um INSERT INTO DestTbl
, oder anstatt die Daten in diesem Format zu speichern, haben Sie jetzt eine Abfrage, um das gewünschte Ergebnis zu erhalten.
Diese Abfragen stellen die Daten im Format:
| 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 wird auch als Transformation in msaccess bezeichnet. Ihre Frage ist insofern einzigartig, als sie auch Text (keine ganzen Zahlen) in den resultierenden Zellen enthält. Die Aggregatfunktion muss immer noch angewendet werden, in diesem Fall sollte MIN() für Textwerte ausreichen, auch wenn nur ein Textwert vorhanden ist. – hamish