2009-07-01 40 views
1

我想將數據從一個垂直分貝佈局這樣的轉移:我怎樣纔能有效地從垂直databaselayout數據傳輸到一個水平一個

 
--------------------- 
| ID | Type | Value | 
--------------------- 
| 1 | 10 | 111 | 
--------------------- 
| 1 | 14 | 222 | 
--------------------- 
| 2 | 10 | 333 | 
--------------------- 
| 2 | 25 | 444 | 
--------------------- 

的水平之一:

 
--------------------------------- 
| ID | Type10 | Type14 | Type25 | 
--------------------------------- 
| 1 | 111 | 222 |  | 
--------------------------------- 
| 2 | 333 |  | 444 | 
--------------------------------- 

創建佈局不是問題,但數據庫相當大,數百萬條目和查詢如果花費很多時間就會被取消。

這怎麼能有效地完成(以便查詢不被取消)。

+0

我相信這是俗稱的樞軸 – dplante 2009-07-01 15:55:30

回答

0
with t as 
(
select 1 as ID, 10 as type, 111 as Value from dual 
union 
select 1, 14, 222 from dual 
union 
select 2, 10, 333 from dual 
union 
select 2, 25, 444 from dual 
) 
select ID, 
max(case when type = 10 then Value else null end) as Type10, 
max(case when type = 14 then Value else null end) as Type14, 
max(case when type = 25 then Value else null end) as Type25 
from t 
group by id 

返回你想要的,我認爲這是更好的方法。 請注意,最大功能就在這裏執行group by子句,任何組函數都可以在這裏使用(如sum,min ...)

+0

偉大的作品,謝謝。 – OliverS 2009-07-02 13:00:16

0

將其分解爲更小的塊,並且不要將整個事件包含在單個事務中。首先,創建表,然後從舊錶執行插入組到新表中。例如,按ID的範圍插入足夠小的塊,以免壓倒數據庫的日誌並花費太長時間。

0

垂直表 - 也稱爲實體屬性值反模式 - 總是成爲一個問題,有時在實施後很短時間。如果您還沒有這樣做,請查看Joe Celko對此策略的評論,您會看到更多證明這種方法有多麻煩的證據。我會在那裏停下來,因爲你是知道來到這個網站的聰明人,而不是那個在你的數據庫中犯下EAV表的犯罪但是善意的派對。

處理這種類型的表的選項並不漂亮,正如您所說的,隨着生產查詢所需數據量的增長,它們會變得更糟/更慢。

  1. 建立一個沒有記錄並保存提交的行,並用它來階段的EAV表內容,將橫版聲明的全局臨時表(DGTT)。 DGTT對於這種剷除數據非常有用,因爲它們不會產生任何日誌開銷。

  2. 採用傳統的CASE和MAX()分組,如前面的建議所示。問題在於每當將新的TYPE引入到EAV表中時查詢都會更改。

  3. 使用DB2的SQL-XML發佈功能將垂直數據轉換爲XML。下面是與表和列名工作的例子您提供:


WITH t(id, type, value) as (
VALUES (1,10,111), (1,14,222), (2,10,333), (2,25,444) 
) 

SELECT 
XMLSERIALIZE(CONTENT 
XMLELEMENT(NAME "outer", 
    XMLATTRIBUTES(id AS "id"), 
     XMLAGG(XMLELEMENT(NAME attr , 
      XMLATTRIBUTES(type as "typeid"), value) ORDER BY type) 
) AS VARCHAR(1024) 
) 
FROM t as t group by id; 

的SQL-XML方法的好處是,由EAV表處理的任何新的值不會需要對重寫值的SQL進行重寫。

相關問題