MySQL 加入后按字段名提取值的子查询

MySQL subquery to pull values by fieldname after join

我正在尝试在 MySQL 中创建一个连接,它将根据字段名从另一个 table 中提取值。我有这 2 tables:

TABLE_MAIN:

ID EVENTID FIELDNAME
1 1 FIELD1
2 1 FIELD2
3 1 FIELD3
4 2 FIELD1
5 3 FIELD2

TABLE_FIELDS:

EVENTID FIELD1 FIELD2 FIELD3
1 Some value text value
2 foo bar text
3 differentValue more text

我正在尝试创建类似下面的东西,我显然不能用普通的连接来做:

ID EVENTID FIELDNAME VALUE
1 1 FIELD1 Some value
2 1 FIELD2 text
3 1 FIELD3 value
4 2 FIELD1 foo
5 3 FIELD2 more

我开始像这样进行简单的连接:

SELECT * FROM TABLE MAIN LEFT JOIN TABLE_FIELDS ON TABLE_MAIN.EVENTID = TABLE_FIELDS.EVENTID

然而,这会引入完整的 table,我如何才能只引入在字段名中指定的字段? 谢谢! 罗伯特

您需要 case 表达式以及 join:

select m.*,
       (case when m.fieldname = 'FIELD1' then f.field1
             when m.fieldname = 'FIELD2' then f.field2
             when m.fieldname = 'FIELD3' then f.field3
        end) as value
from table_main m left join
     table_fields f
     on m.eventid = f.eventid;

您真的应该修复数据模型,以便可以使用联接。如果第二个字段的每个值都在单独的 中,您可以只使用常规联接。

有一种 运行 动态 SQL 的方法,但除非万不得已,否则我绝对不会推荐它。我会采纳 Linoff 先生的建议,即重新设计数据库结构,以便避免这种情况。但是,您可以通过以下方式动态生成 Linoff 先生的查询:

SELECT CONCAT(
    "select m.*, (case ",
    group_concat(distinct CONCAT("WHEN m.fieldname = '", FIELDNAME, "' then f.", FIELDNAME) SEPARATOR " "),
    " end) as value ",
    " from TABLE_MAIN m left join "
    " TABLE_FIELDS f "
    " on m.eventid = f.eventid; "
) INTO @stmt
FROM TABLE_MAIN;

SELECT @stmt;
PREPARE stmt FROM @stmt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

我无法提供 SQL fiddle 来演示,因为我不知道允许动态 sql 执行的 fiddle。我确实使用您的样本数据在本地对其进行了测试,结果如下:

再次强调,不要这样做。有时这是不可避免的,但我认为你可能比处理动态 SQL 更容易调整你的结构。我意识到这不是一个好的解决方案,我不推荐它。