【问题标题】:EAV table select without joins没有连接的 EAV 表选择
【发布时间】:2015-07-10 10:30:48
【问题描述】:

我目前有以下 EAV 表:

id
field_name
field_value

还有一张标准桌子:

id
first_name
last_name

对于与 ID 匹配的每个值,我将标准表加入到 EAV 表中,因此我的查询如下所示:

SELECT id, first_name, last_name, fieldname1, fieldname2
FROM standard_table
LEFT JOIN EAV AS fieldname1 ON 
    (fieldname1.id = standard_table.id AND fieldname1.field_name = 'fieldname1')
LEFT JOIN EAV AS fieldname2 ON 
    (fieldname2.id = standard_table.id AND fieldname2.field_name = 'fieldname2');

这一直运行良好,直到今天我的 EAV 表中有 62 个自定义字段,这意味着我的查询连接到 62 个表,因此达到 MySQL 表连接限制并失败。

整个查询似乎是一种不好的方式,我该如何重写它以便更快并且不需要 62 个表连接。

【问题讨论】:

标签: php mysql join entity-attribute-value


【解决方案1】:

您还可以对 EAV 使用聚合。查询如下:

SELECT st.id, st.first_name, st.last_name,
       MAX(CASE WHEN EAV.field_name = 'fieldname1' THEN fieldname1 END), 
       MAX(CASE WHEN EAV.field_name = 'fieldname2' THEN fieldname2 END)
FROM standard_table st JOIN
     EAV
     ON EAV.id = st.id
GROUP BY st.id, st.first_name, st.last_name;

随着您获得越来越多的列,这可以比几十个连接执行得更好。

【讨论】:

  • 可能是@Mike Oram 需要多行用于单个 id、first_name、last_name,而您的查询只会提供最大值。
  • 我认为这可以做到。该关系在standard_table中只有1行,它连接到EAV中每个字段名称中的1个,所以这就足够了,现在将对其进行测试
  • @ZafarMalik 。 . .如果您愿意,可以使用GROUP_CONCAT() 代替MAX()。 EAV 模型通常每个字段名称都有一个值,某些众所周知的字段除外。
【解决方案2】:

另一个提供的答案是对此的灵感,但我在下面是我实际使用的查询:

SELECT st.id, st.first_name, st.last_name,
   (CASE WHEN `EAV`.`field_name` = 'fieldname1' THEN `EAV`.`field_value` END) AS 'fieldname1', 
   (CASE WHEN `EAV`.`field_name` = 'fieldname2' THEN `EAV`.`field_value` END) AS 'fieldname2', 
FROM standard_table st JOIN
 EAV
 ON EAV.id = st.id
GROUP BY st.id;

【讨论】:

  • 我发现这实际上导致了一个问题,即别名在找到后覆盖了该值
猜你喜欢
  • 2017-07-29
  • 2013-03-15
  • 1970-01-01
  • 1970-01-01
  • 2015-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多