Wenn Sie die UNPIVOT
Funktion auf Daten anwenden, die nicht normalisiert sind, muss der Datentyp und die Länge in SQL Server identisch sein. Ich verstehe, warum der Datentyp gleich sein muss, aber warum erfordert UNPIVOT, dass die Länge gleich ist?
Angenommen, ich habe die folgenden Beispieldaten, die ich zum Deaktivieren benötige:
CREATE TABLE People
(
PersonId int,
Firstname varchar(50),
Lastname varchar(25)
)
INSERT INTO People VALUES (1, 'Jim', 'Smith');
INSERT INTO People VALUES (2, 'Jane', 'Jones');
INSERT INTO People VALUES (3, 'Bob', 'Unicorn');
Wenn ich versuche, die Spalten Firstname
und zu UNPIVOTEN Lastname
, ähnlich wie in:
select PersonId, ColumnName, Value
from People
unpivot
(
Value
FOR ColumnName in (FirstName, LastName)
) unpiv;
SQL Server generiert den Fehler:
Nachricht 8167, Ebene 16, Status 1, Zeile 6
Der Spaltentyp "Nachname" steht in Konflikt mit dem Typ anderer Spalten, die in der UNPIVOT-Liste angegeben sind.
Um den Fehler zu beheben, müssen wir zuerst eine Unterabfrage verwenden, um die Lastname
Spalte mit der folgenden Länge zu konvertieren Firstname
:
select PersonId, ColumnName, Value
from
(
select personid,
firstname,
cast(lastname as varchar(50)) lastname
from People
) d
unpivot
(
Value FOR
ColumnName in (FirstName, LastName)
) unpiv;
Siehe SQL Fiddle with Demo
Bevor UNPIVOT in SQL Server 2005 eingeführt wurde, würde ich ein SELECT
mit verwenden, UNION ALL
um das Pivot der firstname
/ lastname
-Spalten aufzuheben , und die Abfrage würde ausgeführt, ohne dass die Spalten in dieselbe Länge konvertiert werden müssen:
select personid, 'firstname' ColumnName, firstname value
from People
union all
select personid, 'LastName', LastName
from People;
Siehe SQL Fiddle with Demo .
Wir sind auch in der Lage, die Pivot-Funktion der Daten erfolgreich zu deaktivieren, CROSS APPLY
ohne die gleiche Länge für den Datentyp zu haben:
select PersonId, columnname, value
from People
cross apply
(
select 'firstname', firstname union all
select 'lastname', lastname
) c (columnname, value);
Siehe SQL Fiddle with Demo .
Ich habe MSDN durchgelesen, aber ich habe keine Erklärung gefunden, warum die Länge des Datentyps gleich ist.
Welche Logik steckt dahinter, wenn bei UNPIVOT dieselbe Länge erforderlich ist?