2012-01-20 53 views
1
一行

我在那裏一個插件使所有表單提交一個表,在這個表我對每個字段的行這樣的:最有效的方式,採取多行

1 'Name' 'Tony' 
2 'Surname' 'Smith' 
3 'Mail' '[email protected]' 
4 etc. 

我要採取一切這個數據到一個表中所有的數據是在列中,像這樣:

New_Id Name Surname Mail 
    1 'Tony' 'Smith' '[email protected]' 
    2 'Mary' 'DotCom' '[email protected]' 

我有很多這些記錄,所以效率很重要。我的第一種方法是在第一個表中的每個字段上使用PHP循環,然後決定是否必須在第二個表中插入或更新,此解決方案甚至可能需要先前的選擇來查看字段是否已經填充,因此解決方案不是很好不錯。

你能想出更好的解決方案嗎?

編輯:這是我的結構:

這是我的目標表,字段名是西班牙語,但他們的名字,birth_date,ADRESS等

create table target_table 
    (id  int not null AUTO_INCREMENT, 
    blog_id  int, 
    submission_id int, 
    form_id  varchar(250) character set utf8 collate utf8_general_ci, 
    submission_date timestamp, 
    ip  varchar(250) character set utf8 collate utf8_general_ci, 
    sitio   varchar(250) character set utf8 collate utf8_general_ci, 
    nombre  varchar(4000) character set utf8 collate utf8_general_ci, 
    fecha_nacimiento varchar(250), 
    email   varchar(250) character set utf8 collate utf8_general_ci, 
    direccion  varchar(250) character set utf8 collate utf8_general_ci, 
    cp   varchar(250) character set utf8 collate utf8_general_ci, 
    PRIMARY KEY(id)); 

和源實際上是兩個表,cforms_submissions是父母與submission_id,submission_date和電子郵件:

id    int(11) unsigned PK 
form_id   varchar(3) 
sub_date   timestamp 
email   varchar(40) 
ip    varchar(15) 

而且cforms_data是子表字段及其值:

f_id    int(11) unsigned PK 
sub_id   int(11) unsigned <---- This is FK to parent 
field_name  varchar(100) 
field_val  text 

所以,我應該這樣做:

select submissions.... 
for each submission 
    select fields in submissions 
    for each field in submission 
     if first_field 
      insert 
     else 
      update 

也許還有更好的方法嗎?

謝謝你,順便說一句,我與MySQL

+5

當前記錄如何鏈接?例如。你怎麼知道'Name' - >'Tony'與''姓'' - >'Smith''有關? – DaveRandom

+1

至少你正在使用EAV。瞭解您當前的設計將會有所幫助,,, –

+0

表單字段列表是否有限且已經定義? IE,系統或用戶不能添加任意新的密鑰? – jklemmack

回答

2

對不起的工作,我誤解了問題。 只要如果有限的,你可以做N的下列方式連接的表數:

INSERT_INTO target_table(blog_id, form_id, ....) 
SELECT id, ..., name_table.field_val, address_table, ... 
FROM cforms_data name_table INNER JOIN cforms_data address_table 
    ON name_table.sub_id = address_table.sub_id 
    INNER JOIN cforms_data date_table ON name_table.sub_id = name_table.sub_id 
    INNER JOIN ... 
WHERE name_table.field_name = 'NAME' AND address_table.field_name = 'ADDRESS' AND... 

什麼,你正在做的是在目標獲得源匹配字段項子集中的每個領域,併爲那些與其他子集中具有相同ID的字段進行匹配。 由於每個字段都有一個別名,查詢會很痛苦,但如果索引正確(可能在field_name,sub_id上),性能應該不會太差。我認爲你可以在表單中添加field_name比較,但我不確定這是MySQL還是隻有Oracle。 你可能需要對電子郵件中的父母,但我認爲是微不足道的

ORIGINAL:

就在MySQL的執行

INSERT INTO target_table(blog_id,form_id ....)選擇ID,form_id ,, ...,... FROM cforms_submissions INNER JOIN cforms_data的ID == sub_id HAVING MAX(sub_date)

我假設你想插入最後一條記錄。否則,相應地改變SELECT。 INSERT INTO中的字段必須與SELECT中的字段匹配。

+0

你可以提供更多關於查詢的細節嗎?我認爲這對提交是好的,但我關心的是** cforms_data中的每個**字段...... –

+2

查詢中的每個INNER JOIN行都處理目標表中的一個命名字段,只選擇那些字段按姓名匹配,並具有與父母相同的提交ID。因此,例如要獲取「地址」,您可以再次加入整個cforms_data表,並選擇匹配sub_id和field_name ='ADDRESS'的記錄。如果某些字段丟失,則可以使用LEFT JOIN而不是INNER JOIN,並且這些字段在結果中將爲空。 –

+0

關於LEFT_JOIN的好處 – Luis