我有两张桌子:
用户
id |用户
喜欢
id |老板|日期
这个查询:
$owner_result = $connector->query("SELECT id FROM users");
while($owner = $connector->fetchArray($owner_result))
{
$rs = $connector->query("SELECT count(id) AS num FROM likes
WHERE date > DATE_SUB(NOW(), INTERVAL 1 WEEK)
AND owner='$owner[id]'
ORDER BY num DESC LIMIT 5");
while($rw = $connector->fetchArray($rs))
{echo "This owner ($owner[id]) has $rw[num] likes this week";}
}
我想要做的是返回5 users.id 行,其中包含赞表中最大的行数。 我的查询只返回 $ owner [id] ,但不是每个人的喜欢。我认为我的查询的效果也非常低,因为我的查询检查了 likes 表中每个 users.id 的数量,但它可能是喜欢< strong>表格不包含一些 users.id 。
任何有关解决我的问题或改进我的查询的建议都将非常受欢迎。 谢谢。
答案 0 :(得分:1)
您必须在第二个查询中按所有者分组。你不能先计算行数,而不是先将它们分组。
$owner_result = $connector->query("SELECT id FROM users");
while($owner = $connector->fetchArray($owner_result))
{
$rs = $connector->query("SELECT count(id) AS num FROM likes
WHERE date > DATE_SUB(NOW(), INTERVAL 1 WEEK)
AND owner='$owner[id]'
Group BY owner
ORDER BY num DESC LIMIT 5");
while($rw = $connector->fetchArray($rs))
{echo "This owner ($owner[id]) has $rw[num] likes this week";}
}
答案 1 :(得分:1)
您应该加入这两个表,以便您可以在一个语句中获取数据:
SELECT
users.id,
COUNT(likes.id) AS mylikes -- specify a name for the computed column
FROM users
INNER JOIN likes
ON users.id = likes.owner
WHERE date > DATE_SUB(NOW(), INTERVAL 1 WEEK)
GROUP BY users.id
ORDER BY COUNT(likes.id) DESC -- MySQL would allow the alias name
LIMIT 5 -- because you want the top 5
如果存在平局,那么您将失去记录(或更多)。
答案 2 :(得分:1)
我认为单个查询可以获得指定的结果,例如:
SELECT u.id
, COUNT(t.owner) AS cnt_likes
FROM users u
JOIN likes t
ON t.owner = u.id
WHERE t.date > DATE_SUB(NOW(), INTERVAL 1 WEEK)
GROUP BY u.id
ORDER BY 2 DESC
LIMIT 5
likes
表上的适当索引应该可以提高性能:
... ON likes (owner, date)
或者,这将给出相同的结果,可能具有(稍微)更好的性能:
SELECT u.id
, t.cnt_likes
FROM users u
JOIN ( SELECT s.owner
, COUNT(1) AS cnt_likes
FROM likes s
WHERE s.date > DATE_SUB(NOW(), INTERVAL 1 WEEK)
GROUP BY s.owner
) t
ON t.owner = u.id
ORDER BY t.cnt_likes DESC
LIMIT 5
如果确保owner
表中likes
列的所有值都是id
表中的user
值,那么性能会更好。 ..因为您可以避免连接到users表,并从likes
表中获取整个结果:
SELECT s.owner
, COUNT(1) AS cnt_likes
FROM likes s
WHERE s.date > DATE_SUB(NOW(), INTERVAL 1 WEEK)
GROUP BY s.owner
ORDER BY cnt_likes DESC
LIMIT 5
但是,该查询没有进行检查以验证owner
列返回的值是否存在,如id
表的user
列中那样。