我有一个'events'的mysql表,其中包含'category'和'visited'的列。一个事件有3个类别。 'visited'计算活动页面访问次数。我希望从3个类别中的每一个中获得前两个访问过的事件。
这是一个示例表
访问的id类别
32个1 23
33个2 12
34个3 42
35个1 53
36个2 24
37个3 84
38个1 12
39个2 75
40个3 22
我需要按此顺序显示这些行(id =):35,32,39,36,37,34。我所拥有的代码每个类别只返回1行,我相信严格限制为返回1行(我没写过。):
$categories=mysql_query("select distinct category from events");
while($row_cat=mysql_fetch_array($categories)){
$row=mysql_fetch_array(mysql_query("select * from events where category='".$row_cat['category']."' order by visited desc"));
echo $row['id'].", ";
}
该代码显示:35,39,37,
我觉得答案可能非常简单,但它仍然在逃避我。提前谢谢你的帮助。
答案 0 :(得分:1)
怎么样?
SELECT category, GROUP_CONCAT(id ORDER BY visited DESC)
FROM events
GROUP BY category
对于您的原始代码:这是因为您只需要一行。
你的while循环迭代所有类别。对于他们每个人。它发出一个查询并要求一行。您需要2个嵌套循环来查询所有内容。所以“纯粹的MySQL”解决方案要好得多。
但是如果你需要比你原来说的更多,你可能更好地通过嵌套循环PHP-side一个一个地执行这些查询:
$categories=mysql_query("select distinct category from events");
while($row_cat=mysql_fetch_array($categories)){
$inner_res=mysql_query("select * from events where category='".mysql_real_escape_string($row_cat['category'])."' order by visited desc");
while($inner_row=mysql_fetch_array($inner_res)){
echo $inner_row['id'].", ";
}
}
答案 1 :(得分:1)
@glglgl方法非常酷+1,你也可以使用find in set函数来优化它并逐行获得每个类别的前3个事件:
select e0.*
from
events e0
inner join
(SELECT category,
GROUP_CONCAT(id ORDER BY visited DESC) as events
FROM events
GROUP BY category) C
on
e0.category = c.category and
find_in_set( e0.event, c.events ) < 3
小心,如果你有很多事件,这可能会很慢。
免责声明:未经测试。
答案 2 :(得分:0)
SELECT e.*
FROM
( SELECT DISTINCT category
FROM events
) AS ed
JOIN
events AS e
ON e.category = ed.category
AND e.visited >=
( SELECT visited
FROM events AS ei
WHERE ei.category = ed.category
ORDER BY visited DESC
LIMIT 1 OFFSET 1
)