2

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

困扰我的一个项目是我需要一个在一侧有多个对象的连接语句的情况。例如...

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 时,需要是一个包含相关 id(或基于 id 获取的对象)的对象 Foo。

目前,我最终不得不在 PHP 级别压缩多行,将 bar id 添加到 Foo 直到 foo id 更改。这有点难看,但它确实有效。我想减少我的结果集是:

Result from Search:
---------------------
id   barIds   fooData
1    [1,2,3]  ...
2    4        ...
3    5        ...

有没有办法在 SQL 级别做到这一点?(请注意,我不是在寻找文字字符串 1、2、3,我想要一个由 id 的 1、2 和 3 组成的数组——但如果我必须取一个字符串然后转换,我可以做)

顺便说一句,我的意图是将它与 PDO::fetch_class 结合起来,让我在一行中实例化类,而不是花时间编写多行千篇一律的代码来加载类的属性。

4

1 回答 1

4

听起来您正在考虑使用GROUP_CONCAT. 这会将所有酒吧 ID 组合在一起。像这样的东西:

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 演示

- 编辑 -

如果担心 GROUP_CONCAT 默认存储的字符长度(请查看此链接),另一种替代方法是通过执行以下操作来模仿 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
于 2013-02-24T02:23:00.093 回答