我正在重构一些代码,并研究尝试提高可读性和性能的方法。
一个让我烦恼的项目是我需要一端有多个对象的连接语句的情况。例如......
Foo Schema Bar 2 Schema
-------------- ---------------
id id
data fooId
data
Result from Search:
---------------------
id barId fooData
1 1 ...
1 2 ...
1 3 ...
2 4 ...
3 5 ...
我的最终结果是,在查询对象Foo时,需要成为一个对象Foo,其中包含相关的id(或基于id提取的对象)。
目前,我最终必须在PHP级别压缩多行,向foo添加bar id,直到foo id更改为止。它有点难看,但确实有效。我希望将结果集减少为:
Result from Search:
---------------------
id barIds fooData
1 [1,2,3] ...
2 4 ...
3 5 ...
有没有办法在SQL级别执行此操作? (作为一个注释,我没有找到文字字符串1,2,3,我想要一个由id' s 1,2和3组成的数组 - 但是如果我必须取一个字符串然后转换,我可以)
顺便说一句,我的意图是将它与PDO :: fetch_class结合起来,让我在一行中实例化该类,而不是花时间编写多行cookie-cutter代码来加载类的属性。 / p>
答案 0 :(得分:4)
听起来你正在考虑使用GROUP_CONCAT
。这将把所有的条形图组合在一起。像这样:
SELECT F.Id, GROUP_CONCAT(B.Id) BarIds, F.data
FROM Foo F
INNER JOIN Bar B ON F.Id = B.FooId
GROUP BY F.Id
如果您想获得确切的格式,请尝试使用CONCAT
:
CONCAT('[',GROUP_CONCAT(B.Id),']') BarIds
<强> - 编辑 - 强>
如果对GROUP_CONCAT默认存储的字符长度存在疑虑(请检查此link),另一种方法是通过执行以下操作来模仿GROUP_CONCAT的行为:
SELECT Id, BarIds, Data
FROM (
SELECT F.Id,
MAX(@barIdsCombined:=IF(@prevFoodId=F.Id,
CONCAT(@barIdsCombined,',',B.Id),
B.Id)) BarIds,
F.data,
@prevFoodId:=F.Id
FROM Foo F
INNER JOIN Bar B ON F.Id = B.FooId
JOIN (SELECT @barIdsCombined:='') t
GROUP BY F.Id
) t