2013-02-24 52 views
2

我重構了一些代碼,並試圖嘗試提高可讀性和性能。是否可以將多行的結果壓縮到SQL查詢中的一行上的設置對象中?

讓我感到困惑的一件事是我需要一個連接語句的情況,一邊有多個對象。例如...

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(或物體中取出基於標識的),這些相關的對象美孚。

目前,我發現不得不壓縮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

聽起來就像你在使用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存儲的字符長度的關注(檢查了這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 
+0

請小心使用'GROUP_CONCAT',因爲它具有非常低的人爲限制。你可以更新它('group_concat_max_len')。我已經走下了使用MySQL進行聚合的道路,包括'GROUP_CONCAT'。經驗告訴我,使用查詢語言進行聚合通常要好得多,因爲MySQL的權限非常有限 – 2013-02-24 02:26:30

+0

我只使用[和]來表明它可能會以數組的形式訪問PHP,而IIRC - PDO處理SQL集數據類型。 – RonLugge 2013-02-24 03:36:48

+0

@ExplosionPills通過'聚合查詢語言',我假設你的意思是PHP?這真的是一個偉大的想法 - 看起來這對於SQL來說能夠通過後臺查詢優化和緩存來減少開銷來說是一個很好的地方。 – RonLugge 2013-02-24 03:37:50

相關問題