2013-02-04 64 views
0

我有一個非規格化格式的大型數據集。這裏是列名的例子:正常化mySQL中的表數據

foreign_key_ID,P1,P2,P3,P4,P5 .... D1,D2,D3 ....等。

這些字段都含有相似類型數據的。

我需要正常化到我現有的表結構如下:

insert into new_table (id, name, index) 
select foreign_key_id, P1, 1 
from denormalized_table; 

但是,這意味着,我需要在我的非規範化表上運行的每個字段單獨的查詢,只是改變了一些東西:

insert into new_table (id, name, index) 
select foreign_key_id, P2, 2 
from denormalized_table; 

考慮到我有多少這些領域,這會變得單調乏味。

有沒有一種方法可以自動進入單一操作?即:遍歷字段(我不介意在某個地方創建符合條件的字段的列表),拉出字段名稱的最後一位(即「P1」中的「1」和「P2」中的「2」)使用子選擇中的字段名稱和提取的索引號。

回答

1

這裏是一個開始:

SELECT column_name, substr(column_name,2) AS `index` 
    FROM information_schema.columns 
WHERE table_schema = 'mydatabasename' 
    AND table_name = 'denormalized_table' 
    AND column_name REGEXP '^[PD][0-9]+$' 
ORDER BY column_name 

您可以修改選擇列表中的這句話,有MySQL的生成報表您:

SELECT CONCAT('INSERT INTO new_table (id, name, `index`) SELECT foreign_key_id, ' 
     ,column_name,', ',substr(column_name,2) 
     ,' FROM denormalized_table ;') AS stmt 
    FROM information_schema.columns 
WHERE table_schema = 'mydatabasename' 
    AND table_name = 'denormalized_table' 
    AND column_name REGEXP '^[PD][0-9]+$' 
ORDER BY column_name 

從輸出的將是一個然後您可以執行一組MySQL INSERT語句。


如果行要插入的數據的總大小的數量不是太大,你可以和你想在「一個行動」做了整體轉換,那麼你可以生成一個INSERT INTO ... SELECT語句,使用UNION ALL運算符。我會得到廣大聲明是這樣的:

SELECT CONCAT('UNION ALL SELECT foreign_key_id, ' 
     ,column_name,', ',substr(column_name,2) 
     ,' FROM denormalized_table ') AS stmt 
    FROM information_schema.columns 
WHERE table_schema = 'mydatabasename' 
    AND table_name = 'denormalized_table' 
    AND column_name REGEXP '^[PD][0-9]+$' 
ORDER BY column_name 

我將採取從輸出,並與INSERT INTO ...替換第一個UNION ALL。這會給我一個單一的聲明來運行完成整個轉換。

+0

有趣。因此,您建議使用SQL來生成SQL,然後將其複製並粘貼到新的查詢中以實際執行插入操作? –

+0

不,他的查詢結果會爲每行生成一條SQL語句,並且您可以遍歷該結果集並在返回的行上使用EXECUTE。查看我的關於動態SQL的文章。 – Richthofen

+0

@Tom Auger:是的,對於一次性導入數據等管理功能,我將使用SQL和information_schema數據庫來幫助我生成SQL語句。 (我寧願那樣做,而不是做一堆繁瑣的編輯。) – spencer7593

1

你正在尋找的是動態SQL。這是執行SQL語句的地方,您可以通過編程方式進行彙編。只要您處於存儲過程中,您就可以運行任何字符串中的任意SQL代碼。看到這個鏈接:How To have Dynamic SQL in MySQL Stored Procedure

基本上,您可以通過遍歷一組列來使用mySQL語句構建一個字符串。您可以使用SHOW COLUMNS語法(請參見http://dev.mysql.com/doc/refman/5.0/en/show-columns.html)返回集合,然後遍歷該結果集並構建您的動態查詢字符串並執行該操作。

SHOW COLUMNS FROM myTable WHERE Field NOT IN (pkey, otherFieldIDontWantToInclude) 
+0

這是非常有趣的東西,而且我從來沒有嘗試過。結合@ spencer7593的迴應,這可能是我正在尋找的技巧。感謝您的鏈接。 –