2012-05-20 26 views
2

我有三個MySQL表,簡化,下列:連接錶行到列與列標題從原始行

ModuleEntries (MDE_ID) 
ModuleFields (MDF_ID, MDF_Label) 
ModuleEntryFieldValues (MFV_ID, MFV_MDE_ID, MFV_MDF_ID, MFV_Value) 

你可以從簡化列列表中看到,ModuleEntryFieldValues是其中指出,表「對於一個條目,這個字段有這個值」。

現在,我想在一個「平面」記錄集中檢索這些信息。我設法讓事情有效,但並不完全符合我的要求。

有了不同的,所以文章的幫助下,我設法列動態的,可變的量的工作,通過使用遊標。

declare finish int default 0; declare fldid int; declare str varchar(10000) default 'SELECT *,'; declare curs cursor for select MDF_ID from ModuleFields group by MDF_ID; declare continue handler for not found set finish = 1; open curs; my_loop:loop fetch curs into fldid; if finish = 1 then leave my_loop; end if; set str = concat(str, 'max(case when MFV_MDF_ID = ',fldid,' then MFV_Value else null end) as field_',fldid,','); end loop; close curs; set str = substr(str,1,char_length(str)-1); set @str = concat(str, ' from ModuleEntries LEFT join ModuleEntryFieldValues ON MDE_ID = MDF_MDE_ID GROUP BY MDE_ID'); prepare stmt from @str; execute stmt; deallocate prepare stmt;
這段代碼要做的,就是讓我放的MDF_Label的列值的行的實際列標題。現在,上面的代碼給了我「field_1,field_2,...」

是否有可能將這三個表連接起來,並且將MDF_Label作爲現在列中連接表中的行的列標題?

我想這...

ModuleEntries | ModuleFields   | ModuleEntryFieldValues 
------------- | ------------------ | ----------------------------------- 
MDE_ID   | MDF_ID - MDF_Label | MFV_MDE_ID - MFV_MDF_ID - MFV_Value 
1    | 1  - Height  | 1   - 1   - 120cms 
       | 2  - Width  | 1   - 2   - 30cms 
       | 3  - Weight  | 

這個

Recordset 
--------- 
MDE_ID - Height - Width - Weight 
1  - 120cms - 30cms - null 

我希望我的問題是很清晰。如果不是,請評論,如果可以的話,我會在需要時提供更多信息。

+0

看看http://stackoverflow.com/questions/985842/mysql-concat-to-create-column-names的答案。我感覺它可能會幫助你。 –

回答

3

我只是用GROUP_CONCAT()代替光標產生準備好的語句:

SELECT CONCAT(
' SELECT MDE_ID,' 

, GROUP_CONCAT(
    't', MDF_ID, '.MFV_Value AS `', REPLACE(MDF_Label, '`', '``'), '`' 
    ) 

,' FROM ModuleEntries ' 

, GROUP_CONCAT(
    'LEFT JOIN ModuleEntryFieldValues AS t', MDF_ID, ' 
     ON t', MDF_ID, '.MFV_MDE_ID = ModuleEntries.MDE_ID 
     AND t', MDF_ID, '.MFV_MDF_ID = ', MDF_ID 
    SEPARATOR ' ') 

) INTO @qry FROM ModuleFields; 

節省空白編輯,以使其更具可讀性,與您的樣本數據,那麼@qry將包含:

SELECT MDE_ID, 
     t1.MFV_Value AS `Height`, 
     t2.MFV_Value AS `Width`, 
     t3.MFV_Value AS `Weight` 
FROM ModuleEntries 
    LEFT JOIN ModuleEntryFieldValues AS t1 
     ON t1.MFV_MDE_ID = ModuleEntries.MDE_ID AND t1.MFV_MDF_ID = 1 
    LEFT JOIN ModuleEntryFieldValues AS t2 
     ON t2.MFV_MDE_ID = ModuleEntries.MDE_ID AND t2.MFV_MDF_ID = 2 
    LEFT JOIN ModuleEntryFieldValues AS t3 
     ON t3.MFV_MDE_ID = ModuleEntries.MDE_ID AND t3.MFV_MDF_ID = 3 

然後可以準備並執行該聲明:

PREPARE stmt FROM @qry; 
EXECUTE stmt; 
DEALLOCATE PREPARE stmt; 
SET @qry = NULL; 

其產生以下結果:

 
MDE_ID Height Width Weight 
    1 120cms 30cms (null) 

看到它的sqlfiddle

+0

這個解決方案非常優雅,非常感謝! –

+0

當表中沒有記錄時,我收到錯誤。有沒有辦法解決這個問題? '你的SQL語法有錯誤;檢查對應於你的MySQL服務器版本使用附近的「NULL」在行1' –

+0

@UwConcept正確的語法手冊:將逗號後'MDE_ID'到'GROUP_CONCAT'和定義'SEPARATOR「」'。 – eggyal