2012-01-26 41 views
2

按組進行分組各組內的uniq的屬性項目我有簡單的SQL:只選擇3初入by子句

SELECT foos.*, bars.* FROM foos 
    LEFT JOIN bars ON bars.foo_id = foos.id 
    WHERE foos.id = 1; 

=>

+------------------------------------+ 
| foos.id | bars.id | bars.author_id | 
+------------------------------------+ 
| 1 | 1 |  10  | 
| 1 | 3 |  10  | 
| 1 | 5 |  3  | 
| 1 | 6 |  10  | 
| 1 | 7 |  10  | 
| 1 | 8 |  10  | 
| 1 | 44 |  11  | 
| 1 | 32 |  10  | 
+------------------------------------+ 

現在我需要回到並不是所有加盟bars,但每個bars.author_id只有前三個(切片),因此它可以有效地返回類似的內容

+------------------------------------+ 
| foos.id | bars.id | bars.author_id | 
+------------------------------------+ 
| 1 | 1 |  10  | 
| 1 | 3 |  10  | 
| 1 | 5 |  3  | 
| 1 | 6 |  10  | 
| 1 | 44 |  11  | 
+------------------------------------+ 
+0

這是一個錯字'LEFT JOIN酒吧ON bars.foo_id = bars.id',不是嗎?當然:) THX – dgw

+0

這是一個常見的問題。試試[最大正每組(http://stackoverflow.com/questions/tagged/greatest-n-per-group)標記問題或右邊的鏈接,**下**相關。 – fl00r

+2

的 –

回答

1

我對此有一個很好的解決方案:

For, selecting 1st 3 record within each group 
1) sorting the results asc/desc by applying `order by bars.id` within group_concat() 
2) limiting the records by passing the 3rd parameter as the records to limit to SUBSTRING_INDEX(str,'match str','no of records to limit') 

SELECT foos.id, 
     SUBSTRING_INDEX(GROUP_CONCAT(bars.id 
         order by bars.id),',',3), 
     bars.author_id 

FROM foos LEFT JOIN bars ON bars.foo_id = foos.id 

WHERE foos.id = 1 
GROUP BY bars.author_id 

其結果將是:

+------------------------------------+ 
| foos.id | bars.id | bars.author_id | 
+------------------------------------+ 
| 1 | 1,3,6 |  10 | 
| 1 | 5  |  3 | 
| 1 | 44  |  11 | 
+------------------------------------+ 

後來,在應用端可以通過爆發,「 ,'並使用它。

+0

哇。聰明! :)我明天會嘗試 – fl00r

1

你可以嘗試:

SELECT f.*, b.* 
FROM foos f 
LEFT JOIN (select b1.* 
      from bars b1 
      where 3 < (select count(*) 
         from bars bn 
         where bn.foo_id = b1.foo_id and 
          bn.author_id = b1.author_id and 
          bn.id < b1.id) 
      ) b 
     ON b.foo_id = f.id 
WHERE f.id = 1; 
0
SELECT 
     foos.* 
    , bars.* 
FROM 
     foos 
    LEFT JOIN 
     bars 
    ON bars.foo_id = foos.id 
    AND bars.author_id <= COALESCE(
     (SELECT b.author_id 
     FROM bars b 
     WHERE b.foo_id = foos.id 
     ORDER BY b.author_id ASC 
     LIMIT 0 OFFSET 2   --- one less than 3 
     ), 2147483647    ) 
WHERE 
     foos.id = 1 

bars(foo_id, author_id)的索引將幫助,如果它的速度慢。