2016-08-30 142 views
1

我正在使用UNPIVOT運算符,並且正在返回不需要的數據類型。查詢返回未轉發數據的nvarchar數據類型。當我加入一個varchar數據類型的表時,我得到一個隱式類型轉換。下面是一個將會產生這些結果的例子。UNPIVOT返回數據類型

有沒有辦法控制UNPIVOT返回的輸出數據類型?我想有UNPIVOT返回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 
+0

我在2008年執行了這個,但沒有看到任何錯誤 – techspider

+0

它沒有錯誤。如果您查看查詢計劃,您將看到隱式類型轉換。這正是我想要避免的。 –

+0

你可以更好地用你所看到的更新你的問題! – techspider

回答

4

UNPIVOT函數是一個位,這將需要從數據各列(具有相同的數據類型和長度),並將其轉換爲行的奇函數的。

雖然它轉換數據,但它似乎一直在做一些假設。例如,您的Volume列獲取int的數據類型,因爲這是您未轉義的每個列的數據類型,但問題在於您的VolumeType列 - 引擎不知道您的數據是否有varcharnvarchar,所以當你執行unpivot時,它會給出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;  

See Demo

您的問題與我在DBA.SE上發佈的關於UNPIVOT要求所有數據類型長度相同的原因非常相似。