2011-05-24 57 views
3

我有一個非常大的查詢來提取有關各國報告的信息,而現在,我可以限制這個的唯一方法是將Limit 10或某個數字放在最後,這將限制各個國家/地區。然而,我想要做的就是將group_concat限制爲每個國家/地區的10個結果,在我的情況下,該結果將以某種方式限制10個單詞group_concat的每個實例。是否有人發現了一種限制group_concat行的(簡單)方法?

我當前的查詢是:

SELECT country, 
GROUP_CONCAT(docID), 
GROUP_CONCAT(analyst), 
GROUP_CONCAT(region), 
GROUP_CONCAT(report), 
GROUP_CONCAT(topic), 
MAX((date)) AS date, 
MAX((docID)) AS docID, 
GROUP_CONCAT(date) AS dates, 
GROUP_CONCAT(event) AS events, 
GROUP_CONCAT(province) AS provinces 
FROM reports GROUP BY country 
ORDER BY date DESC, docID DESC 

我已經看到了這個問題問了,我還沒有看到任何真正的好答案。我知道這個函數沒有內置到MySQL中,因爲你只能根據字符進行限制。有沒有人解決過這個問題?

+1

的帖子我認爲你必須做一個「每組前N個」查詢和應用GROUP_CONCAT其結果。 – 2011-05-24 19:36:31

+0

哇,這可能是很多額外的代碼來編寫。會惹一下它。 – 2011-05-24 19:40:19

+0

Gah ...不要使用重複的字符串連接。使查詢難以閱讀。使用heredoc(php.net/heredoc),這樣你就可以擁有一些PHP所包圍的「純粹」sql。 – 2011-05-24 19:49:57

回答

2

解決方法
一個選項是墊你的價值觀與 空間 #。因此,group_concat中的每個項目都是相同的長度。
假設沒有超過20個字符的項目。

然後將查詢將是:

SET group_concat_max_len = 10*20+9; /*execute this first.*/ 
/*10 items, 20 bytes each + 9 bytes for the separator*/ 

SELECT country, 
REPLACE(GROUP_CONCAT(RIGHT(CONCAT(repeat('#',20),docID),20)),'#','') AS docIDs, 
REPLACE(GROUP_CONCAT(RIGHT(CONCAT(repeat('#',20),analyst),20)),'#','') AS analysts, 
REPLACE(GROUP_CONCAT(RIGHT(CONCAT(repeat('#',20),region,20)),'#','') AS regions, 
REPLACE(GROUP_CONCAT(RIGHT(CONCAT(repeat('#',20),report,20)),'#','') AS reports, 
REPLACE(GROUP_CONCAT(RIGHT(CONCAT(repeat('#',20),topic,20)),'#','') AS topics, 
MAX((date)) AS `date`, /* LATEST DATE*/ 
MAX((docID)) AS docID, /* LATEST DOC*/ 
REPLACE(GROUP_CONCAT(RIGHT(CONCAT(repeat('#',20),date,20)),'#','') AS dates, 
REPLACE(GROUP_CONCAT(RIGHT(CONCAT(repeat('#',20),event,20)),'#','') AS events, 
REPLACE(GROUP_CONCAT(RIGHT(CONCAT(repeat('#',20),province,20)),'#','') AS provinces 
FROM reports 
GROUP BY country ORDER BY `date` DESC, docID DESC 

只是爲了回顧:

x= CONCAT(repeat('#',20),docID) adds 20 x #################### in front of docID 
y= RIGHT(X,20)     Takes the rightmost 20 chars of that 
z= GROUP_CONCAT(y)    strings these together up to max_len 
result = REPLACE(z,'#','') removes the `#` so the result looks normal. 

或者自己寫GROUP_CONCAT
的版本,您可以使用自己的GROUP_CONCAT UDF。
有幾個例子在網上浮動。

例如爲:http://www.codeproject.com/KB/database/mygroupconcat.aspx?display=Mobile

+0

這是非常好的。現在看看這個。 – 2011-05-24 20:11:31

+0

@RVWard,因爲你沒有顯示** group_concat的所有**值,所以你可以考慮把語句改成'group_concat(x order by'date' desc,docID desc),否則你可能會得到意想不到的結果。 'Group_concat'需要它自己的訂單子句。 – Johan 2011-05-24 20:15:35

+0

非常酷。很有幫助。很感謝。 – TheCarver 2012-07-11 15:17:00

2

這裏是我的榜樣之一,限制每個用戶

select user_id,SUBSTRING_INDEX(group_concat(posts.id order by rand()),',',3) from posts inner join users on users.id = posts.user_id group by posts.user_id; 
相關問題