是否可以将多行的结果压缩到SQL查询中一行的set对象中?

时间:2013-02-24 02:17:39

标签: mysql sql pdo

我正在重构一些代码,并研究尝试提高可读性和性能的方法。

一个让我烦恼的项目是我需要一端有多个对象的连接语句的情况。例如......

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>

1 个答案:

答案 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

这是SQL Fiddle Demo

<强> - 编辑 -

如果对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