EAV查询动态字段转列:多表关联下动态字段转为结果列的SQL问题咨询
解决思路
你的需求属于典型的动态行转列场景,因为关联的Fields字段数量不固定,无法直接写死查询列名,MySQL环境下可以通过动态拼接SQL+预处理执行的方式实现。
实现代码
-- 可选:如果字段数量较多,先调大GROUP_CONCAT长度限制,避免SQL被截断 SET SESSION group_concat_max_len = 1000000; -- 设置要查询的目标dataentry ID,可替换为实际值 SET @target_dataentry_id = 1; -- 动态生成所有字段对应的查询列逻辑 SET @dynamic_cols = NULL; SELECT GROUP_CONCAT(DISTINCT CONCAT( 'MAX(CASE WHEN f.name = ''', name, ''' THEN dv.value END) AS `', name, '`' ) ) INTO @dynamic_cols FROM Fields WHERE dataentry_id = @target_dataentry_id; -- 拼接完整查询语句 SET @full_query = CONCAT(' SELECT dr.id AS dataentry_row_id, ', @dynamic_cols, ' FROM DataentryRows dr LEFT JOIN DataentryValue dv ON dr.id = dv.dataentry_row_id LEFT JOIN Fields f ON dv.field_id = f.id AND f.dataentry_id = ', @target_dataentry_id, ' WHERE dr.dataentry_id = ', @target_dataentry_id, ' GROUP BY dr.id '); -- 执行预处理语句得到结果 PREPARE stmt FROM @full_query; EXECUTE stmt; DEALLOCATE PREPARE stmt;
逻辑说明
- 第一步先从Fields表过滤出目标dataentry关联的所有字段,通过
GROUP_CONCAT把每个字段拼接成MAX(CASE WHEN 字段名 = 'xxx' THEN 对应值 END) AS 字段名的格式,实现动态生成列的逻辑。 - 关联查询时按DataentryRows的ID分组,
MAX函数的作用是提取分组内对应字段的非空值,同一个分组内不会出现多个同字段的匹配值,用MIN也可以达到相同效果。
内容的提问来源于stack exchange,提问作者Kerby82
相关产品推荐
相关产品推荐

