2011-05-24 56 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; 
相关问题