2013-04-23 81 views
0

我有一個狹窄的實體ID和屬性標識符表。對於每一行都有一個數字值或一個字符串。我想轉出數據,但這對於不同類型的值域是很困難的。不同數據類型的兩個字段的PIVOT

目前,我將數值轉換爲文本,然後再次轉換爲數字。這導致了格式問題,我擔心它效率低下。這些數據將被稱爲計算的很多,這意味着大量的轉換(更不用說精度損失,可維護性差等)。

我們以這種方式構建表格的原因是它允許存儲數據的靈活性。並非所有實體都具有所有屬性,並且我們可能會在未來添加更多屬性。我們不希望表格更改影響下游代碼。另外,我們實際上並沒有在每行中存儲屬性名稱,而是存儲整數ID。就這個例子而言,我使用了一個字符串而不是數字ID來簡化代碼/理解。

什麼是擺脫不同數據類型字段的正確方法?

下面是當前的表結構的一個例子:一邊

declare @temp table 
(
    EntityID int, 
    AttributeName varchar(500), 
    NumberValue float, 
    StringValue varchar(500), 
    IsText bit 
) 

insert into @temp (EntityID,AttributeName,NumberValue,StringValue,IsText) 
select 1,'Year',1776,null,0 

insert into @temp (EntityID,AttributeName,NumberValue,StringValue,IsText) 
select 1,'Note',null,'The year our country declared independence',1 

insert into @temp (EntityID,AttributeName,NumberValue,StringValue,IsText) 
select 2,'Year',1988,null,0 

insert into @temp (EntityID,AttributeName,NumberValue,StringValue,IsText) 
select 2,'Note',null,'The year Die Hard was released',1 

select 
EntityID, YearNum=convert(float, [Year]), Note 
from 
(
select 
    EntityID, 
    AttributeName, 
    Value=Case when IsText=1 then StringValue else convert(varchar(500), NumberValue) end 
from 
    @temp 
) A 
pivot 
(
    Max(Value) for AttributeName in 
    (
     [Year], 
     Note 
    ) 
) P 
+0

爲什麼你需要將它轉換爲「浮動」的最終顯示?爲什麼不把數據保留爲varchar? – Taryn 2013-04-23 14:15:34

+0

@bluefeet因爲在我的系統中,這些數字在報告中使用。爲了討論的目的,我在這裏簡化了數據 – FistOfFury 2013-04-23 14:24:48

回答

3

設計的問題,我實在看不出使用PIVOT的需求,除非你想讓你的查詢返回列的動態數量。否則,你可以做這樣的事情:

SELECT EntityID, 
     MAX(CASE WHEN AttributeName = 'Year' THEN NumberValue END) YearNum, 
     MAX(CASE WHEN AttributeName = 'Note' THEN StringValue END) Note 
FROM @temp 
GROUP BY EntityID 
+0

不是更高效的數據透視嗎? – FistOfFury 2013-04-23 14:22:09

+0

@FistOfFury你將不得不測試它,但可能不是在這種情況下 – Taryn 2013-04-23 14:23:29

+0

@Lamak你是什麼意思的「動態與列數」? – FistOfFury 2013-04-23 14:26:08

相關問題