我有三个简化的MYSQL表,包括以下列:
ModuleEntries (MDE_ID)
ModuleFields (MDF_ID, MDF_Label)
ModuleEntryFieldValues (MFV_ID, MFV_MDE_ID, MFV_MDF_ID, MFV_Value)
从简化列列表中可以看出,ModuleEntryFieldValues
是表“对于条目,此字段具有此值”的表。
现在,我想在一个“扁平”记录集中检索此信息。我设法使事情有效,但并不完全符合我的要求。
在另一篇SO文章的帮助下,我设法通过使用游标获得动态,可变数量的列。
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 :(得分: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上查看。