2

私はいくつかのコードをリファクタリングしていて、読みやすさとパフォーマンスの両方を改善しようとする方法を探しています。

私を悩ませている項目の1つは、片側に複数のオブジェクトがある結合ステートメントが必要な状況です。例えば...

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レベルで複数の行を凝縮する必要があり、fooidが変更されるまで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と組み合わせて、クラスのプロパティをロードするために何行ものcookie-cutterコードを書くのに時間を費やす代わりに、クラスを1行でインスタンス化できるようにすることです。

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 Demoです。

- 編集 -

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 に答える