使用GROUP_CONCAT生成一个可以像查询字符串一样读取的值

时间:2015-03-05 13:48:19

标签: mysql group-concat

我知道这有其局限性,但正如我现在已经使用了几次,我想我应该检查一下它是否可以接受,或者在我再次使用它之前是否有更好的方法!

基本上,我从MySQL数据库中提取了许多产品。每个产品行都链接到许多其他表,但特别是属性表,其中可以设置自定义属性(名称和值对)。

我希望查询为每个产品生成一行,尽管产品可能具有多少“属性”,而不是之后必须操纵结果集。

所以,我做了类似的事情:

SELECT 
GROUP_CONCAT(DISTINCT CONCAT(pp.name, '=', pp.value) SEPARATOR '&') 
AS properties 
FROM products p
INNER JOIN properties pp ON pp.product_id = p.id
WHERE ...

..这导致格式为properties的{​​{1}}字段,然后我可以使用name1=value1&name2=value2轻松转换为PHP数组,并分配给产品对象供以后使用。< / p>

每个人如何看待这种方法?你会怎么做?

注意:只是为了澄清一下,我没有将属性名称直接映射到PHP变量(我同意这会非常糟糕),我正在使用parse_str($str, $output);属性为数组parse_str($str, $output),而不是直接转换为变量。

3 个答案:

答案 0 :(得分:0)

更好的方法是循环通过没有group by的行,并在应用程序(在你的情况下是PHP)处理数组。

$array[$row->group_by_key][$row->name] = $row->value;

假设group_concat包含value&,当前=出现问题的可能性很大。然后你必须在它们进入或动态之前逃脱它们。

我知道你说你想把它全部放在一排,但为什么呢?如果以任何一种方式对其进行解析会产生影响吗?

答案 1 :(得分:0)

这可行,但似乎有点危险。代码正在做出一些可能使它变得脆弱的假设。也就是说,未来的微小变化可能会破坏这种方法。

一个假设是PHP中的变量与数据库中的名称完全相同。当然,现在确实如此,但只要等到有人想要结合“城市&#34;和&#34;州&#34;到一个位置属性 - 反之亦然。换句话说,向前推进逻辑可能不仅仅是简单的分配。

另一个假设是您的值是数字的(我认为字符串需要引号)。

第三个假设是数据库和应用程序层之间的依赖关系。 group_concat()仅受MySQL支持。另一个应用程序工具可能不会以完全相同的方式支持parse_str()

但是,我承认,这是获取属性的一个聪明的解决方案。如果您打算采用这种方法,我建议您至少将查询放入存储过程(比如usp_GetAllParameters)并使用存储过程作为接口。这至少将数据库与应用程序工具分开。

答案 2 :(得分:-1)

您可以尝试:

SELECT 
 p.id,
  GROUP_CONCAT(CONCAT(pp.name,'=',pp.value) SEPARATOR '&') AS properties
FROM products  p
LEFT JOIN (
  SELECT product_id, name, MAX(value)
  FROM properties 
  GROUP BY product_id, name
) pp
ON pp.product_id = p.id
GROUP by p.id

或者,如果您在每个product_id + name

的pp表中都没有多条记录
SELECT 
 p.id,
  GROUP_CONCAT(CONCAT(pp.name,'=',pp.value) SEPARATOR '&') AS properties
FROM products  p
LEFT JOIN (
  SELECT DISTINCT product_id, name, value
  FROM properties 
) pp
ON pp.product_id = p.id
GROUP by p.id