UNPIVOT Return 数据类型
UNPIVOT Return Data Types
我正在使用 UNPIVOT
运算符,但得到了不需要的数据类型 returned。查询是 returning 非透视数据的 nvarchar 数据类型。当连接到具有 varchar 数据类型的 table 时,我得到了一个隐式类型转换。下面是将产生这些结果的示例。
有没有办法控制 return 由 UNPIVOT
编辑的输出数据类型?我想要 UNPIVOT
return varchar 数据类型。
CREATE TABLE #Data
(
Facility varchar(10) NOT NULL,
Dt datetime NOT NULL,
VolumeType1 int NOT NULL,
VolumeType2 int NOT NULL,
VolumeType3 int NOT NULL
);
CREATE TABLE #Map
(
Facility varchar(10) NOT NULL,
Department varchar(15) NOT NULL,
VolumeType varchar(15) NOT NULL
)
INSERT INTO #Data VALUES
('Building1', '08/01/2016', 2500, 2500, 30),
('Building1', '08/02/2016', 3000, 3000, 35),
('Building2', '08/01/2016', 2500, 2500, 30),
('Building2', '08/02/2016', 3000, 3000, 35)
INSERT INTO #Map VALUES
('Building1', 'Department1', 'VolumeType1'),
('Building1', 'Department2', 'VolumeType2'),
('Building2', 'Department3', 'VolumeType1')
SELECT
*
FROM
#Data
UNPIVOT
(
Volume FOR VolumeType IN (VolumeType1, VolumeType2, VolumeType3)
) AS UNP
JOIN #Map
ON UNP.Facility = #Map.Facility
AND UNP.VolumeType = #Map.VolumeType
UNPIVOT 函数有点奇怪,因为它会从不同的列(具有相同的数据类型和长度)获取数据并将其转换为行。
虽然它会转换数据,但它似乎会在此过程中做出一些假设。例如,您的 Volume
列获得 int 的数据类型,因为这是您取消透视的每个列的数据类型,但问题出在您的 VolumeType
列上 - 引擎不知道您是否有数据的 varchar
或 nvarchar
,因此当您执行逆透视时,它会给出 nvarchar(256)
.
如果您不想要隐式类型转换,那么我建议您使用 CROSS APPLY
来逆透视您的数据。这是几行代码,但如果需要,您可以包含显式数据类型。这是一个例子:
select *
from
(
select Facility, Dt, VolumeType, Volume
from #Data
cross apply
(
select 'VolumeType1', VolumeType1 union all
select 'VolumeType2', VolumeType2 union all
select 'VolumeType3', VolumeType3
) c (VolumeType, Volume)
) UNP
JOIN #Map
ON UNP.Facility = #Map.Facility
AND UNP.VolumeType = #Map.VolumeType;
See Demo。这应该删除隐式转换,但如果没有,则可以在 CROSS APPLY
:
内部执行转换
select *
from
(
select Facility, Dt, VolumeType, Volume
from #Data
cross apply
(
select cast('VolumeType1' as varchar(15)), VolumeType1 union all
select cast('VolumeType2' as varchar(15)), VolumeType2 union all
select cast('VolumeType3' as varchar(15)), VolumeType3
) c (VolumeType, Volume)
) UNP
JOIN #Map
ON UNP.Facility = #Map.Facility
AND UNP.VolumeType = #Map.VolumeType;
您的问题与我在 DBA.SE 上发布的关于为什么 UNPIVOT 要求所有数据类型长度相同的问题非常相似。
我正在使用 UNPIVOT
运算符,但得到了不需要的数据类型 returned。查询是 returning 非透视数据的 nvarchar 数据类型。当连接到具有 varchar 数据类型的 table 时,我得到了一个隐式类型转换。下面是将产生这些结果的示例。
有没有办法控制 return 由 UNPIVOT
编辑的输出数据类型?我想要 UNPIVOT
return varchar 数据类型。
CREATE TABLE #Data
(
Facility varchar(10) NOT NULL,
Dt datetime NOT NULL,
VolumeType1 int NOT NULL,
VolumeType2 int NOT NULL,
VolumeType3 int NOT NULL
);
CREATE TABLE #Map
(
Facility varchar(10) NOT NULL,
Department varchar(15) NOT NULL,
VolumeType varchar(15) NOT NULL
)
INSERT INTO #Data VALUES
('Building1', '08/01/2016', 2500, 2500, 30),
('Building1', '08/02/2016', 3000, 3000, 35),
('Building2', '08/01/2016', 2500, 2500, 30),
('Building2', '08/02/2016', 3000, 3000, 35)
INSERT INTO #Map VALUES
('Building1', 'Department1', 'VolumeType1'),
('Building1', 'Department2', 'VolumeType2'),
('Building2', 'Department3', 'VolumeType1')
SELECT
*
FROM
#Data
UNPIVOT
(
Volume FOR VolumeType IN (VolumeType1, VolumeType2, VolumeType3)
) AS UNP
JOIN #Map
ON UNP.Facility = #Map.Facility
AND UNP.VolumeType = #Map.VolumeType
UNPIVOT 函数有点奇怪,因为它会从不同的列(具有相同的数据类型和长度)获取数据并将其转换为行。
虽然它会转换数据,但它似乎会在此过程中做出一些假设。例如,您的 Volume
列获得 int 的数据类型,因为这是您取消透视的每个列的数据类型,但问题出在您的 VolumeType
列上 - 引擎不知道您是否有数据的 varchar
或 nvarchar
,因此当您执行逆透视时,它会给出 nvarchar(256)
.
如果您不想要隐式类型转换,那么我建议您使用 CROSS APPLY
来逆透视您的数据。这是几行代码,但如果需要,您可以包含显式数据类型。这是一个例子:
select *
from
(
select Facility, Dt, VolumeType, Volume
from #Data
cross apply
(
select 'VolumeType1', VolumeType1 union all
select 'VolumeType2', VolumeType2 union all
select 'VolumeType3', VolumeType3
) c (VolumeType, Volume)
) UNP
JOIN #Map
ON UNP.Facility = #Map.Facility
AND UNP.VolumeType = #Map.VolumeType;
See Demo。这应该删除隐式转换,但如果没有,则可以在 CROSS APPLY
:
select *
from
(
select Facility, Dt, VolumeType, Volume
from #Data
cross apply
(
select cast('VolumeType1' as varchar(15)), VolumeType1 union all
select cast('VolumeType2' as varchar(15)), VolumeType2 union all
select cast('VolumeType3' as varchar(15)), VolumeType3
) c (VolumeType, Volume)
) UNP
JOIN #Map
ON UNP.Facility = #Map.Facility
AND UNP.VolumeType = #Map.VolumeType;
您的问题与我在 DBA.SE 上发布的关于为什么 UNPIVOT 要求所有数据类型长度相同的问题非常相似。