我知道这有其局限性,但正如我现在已经使用了几次,我想我应该检查一下它是否可以接受,或者在我再次使用它之前是否有更好的方法!
基本上,我从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)
,而不是直接转换为变量。
答案 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
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