限制 GROUP_CONCAT() 或 INNER JOIN 的结果
Posted
技术标签:
【中文标题】限制 GROUP_CONCAT() 或 INNER JOIN 的结果【英文标题】:Limit results on an GROUP_CONCAT() or INNER JOIN 【发布时间】:2012-04-28 19:51:04 【问题描述】:我已经广泛阅读了其他讨论 group_concat() 和内部连接限制的线程,但没有找到我的答案,所以我想我会继续问它:
我正在开发一个现有的照片社区网站。我想检索在给定日期(今天)过生日的成员,然后检索每个成员的 5 张评价最高的照片。但我也只想要 10 个“最喜欢”的生日成员(即最喜欢的人数)。这是我所拥有的:
SELECT users.user_id, users.user_name,
GROUP_CONCAT(CONVERT(photos.photo_id,char(32))
ORDER BY photos.average_rate) as photo_ids
FROM users
INNER JOIN photos ON photos.user_id=users.user_id
WHERE users.day_of_birth = DATE_FORMAT('2012-04-17', '%m-%d')
AND users.photo_count>0
GROUP BY users.user_id
ORDER BY users.favorite_count DESC, users.photo_count DESC LIMIT 0,10
这是我想要的,除了我不能将photo_id
s 的数量限制为 5。这是一个问题,因为输出将作为 JSON 发送到应用程序,并且一些成员已经上传了超过 20,000 张照片,导致输出字符串过长。似乎对我有用的唯一“解决方案”是将服务器变量 group_concat_max_len
设置为合理的值,至少可以容纳 5 个 id,但这非常笨拙且不可靠。有没有办法通过单个查询为每个用户准确返回 5 个photo_id
s?或者我需要在我的 php 中做一个循环吗?
我不一定需要逗号分隔值中的 photo_id,如果更可行的话,我也可以完全放弃 group_concat() 方法并进行内部连接。但即使在那里,我也不知道有什么方法可以将结果限制为 5。
【问题讨论】:
检查[greatest-n-per-group]
标签或右侧相关下的问题。
我环顾四周,但找不到适合我特定情况的答案......或者我的 SQL-fu 不足以为我的情况实施它(更可能是后者)。
【参考方案1】:
这些高级功能让我爱上了 mysql :)
SELECT user_id, user_name,
GROUP_CONCAT(CONVERT(photo_id, char(32)) ORDER BY photos.average_rate) as photo_ids
FROM ( SELECT user_id, user_name, photo_id, favorite_count, photo_count,
(case when @user_id = user_id then @rownum := @rownum + 1 else CONCAT(@rownum := 1, @user_id := user_id) end) AS dummy_val
FROM ( SELECT users.user_id, users.user_name, users.favorite_count, users.photo_count, photos.photo_id
FROM users
INNER JOIN photos
ON photos.user_id=users.user_id
WHERE users.day_of_birth = DATE_FORMAT('2012-04-17', '%m-%d')
AND users.photo_count > 0
ORDER BY users.id ASC, photos.average_rate ASC
) AS h,
( @rownum := NULL,
@user_id := NULL
) AS vars
HAVING rownum <= 5) AS h2
GROUP BY user_id
ORDER BY favorite_count DESC, photo_count DESC LIMIT 0, 10
基本上我得到所有行,并丢弃计算出的rownum中6或更高的所有照片。
【讨论】:
【参考方案2】:SELECT u.user_id
, u.user_name
, GROUP_CONCAT(p.photo_id ORDER BY p.average_rate) AS photo_ids
FROM
( SELECT user_id
, user_name
, favorite_count
, photo_count
FROM users
WHERE day_of_birth = DATE_FORMAT('2012-04-17', '%m-%d')
AND photo_count > 0
ORDER BY favorite_count DESC
, photo_count DESC
LIMIT 10
) AS u
INNER JOIN
photos AS p
ON p.user_id = u10.user_id
AND p.average_rate >=
( SELECT pp.average_rate
FROM photos AS pp
WHERE pp.user_id = u10.user_id
ORDER BY pp.average_rate DESC
LIMIT 1 OFFSET 4
)
GROUP BY u.user_id
ORDER BY u.favorite_count DESC
, u.photo_count DESC
【讨论】:
以上是关于限制 GROUP_CONCAT() 或 INNER JOIN 的结果的主要内容,如果未能解决你的问题,请参考以下文章