MySQL:在子查询的WHERE语句中使用CONCAT()作为列名

时间:2014-01-31 09:47:30

标签: mysql subquery concat

这是我关于stackoverflow的第一个问题,但到目前为止我已经阅读了多年。如果我的问题不合适,请原谅。我一直在网上搜索几个小时,但没找到任何东西。

我目前正在优化在MySQL数据库上工作的系统的查询。一张表持有另一张表的总和以加快显示这些总和的前端。我最终得到的查询是替换代码中的多个其他查询和循环......如果它可以正常工作:)

这是一个没有按预期工作的人:

SELECT 
v.*, 
(
  SELECT COUNT(DISTINCT i.display_item_id)
  FROM search_index_item i
  WHERE i.path LIKE '238/2/257/%'
  AND i.scope_id = v.scope_id
  AND CONCAT('i.attribute_', v.attribute_id) LIKE CONCAT('%|', v.attribute_value_id, '|%')
) 
AS item_count
FROM search_index_category_attribute_value v
WHERE v.category_id = 257

查询到目前为止工作,但计算的“item_count”始终为0.其0为语句“CONCAT('i.attribute_',v.attribute_id)”的原因似乎不是作为字段名称。当我用好的列名替换此语句时,它返回一个值:

SELECT 
v.*, 
(
  SELECT COUNT(DISTINCT i.display_item_id)
  FROM search_index_item i
  WHERE i.path LIKE '238/2/257/%'
  AND i.scope_id = v.scope_id
  AND i.attribute_7 LIKE CONCAT('%|', v.attribute_value_id, '|%')
) 
AS item_count
FROM search_index_category_attribute_value v
WHERE v.category_id = 257

这现在有效,但当然只适用于一个attribute_id(7)。由于属性ID存储在另一个表中,然后为了性能目的而在非规范化表中保存为单列,我需要动态创建列名。当然我可以在代码中完成它,但这是相当慢和不需要的。

你们是否知道如何强制MySQL处理“CONCAT('i.attribute_',v.attribute_id)”作为字段而不是字符串?

提前谢谢!

1 个答案:

答案 0 :(得分:0)

您的数据模型存在缺陷 如果无法规范化数据,请尝试重写此子句:

AND CONCAT('i.attribute_', v.attribute_id) LIKE CONCAT('%|', v.attribute_value_id, '|%')

进入这个怪物:

AND CASE v.attribute_id 
       WHEN 1 THEN i.attribute_1
       WHEN 2 THEN i.attribute_2
       WHEN 3 THEN i.attribute_3
       WHEN 4 THEN i.attribute_4
       .......
       .......
       .......
       WHEN 998 THEN i.attribute_998 
       WHEN 999 THEN i.attribute_999  
       WHEN 1000 THEN i.attribute_1000
   END
 LIKE CONCAT('%|', v.attribute_value_id, '|%')   

这可能会起作用,但它不会很快 - 这个查询必须始终进行全表扫描,它不能使用任何索引。