我有一个查询。
SELECT * FROM users LEFT JOIN ranks ON ranks.minPosts <= users.postCount
每次匹配时返回一行。通过使用GROUP BY users.id
,我将每行作为单独的ID。
然而,当他们分组我只获得第一行。我想改为ranks.minPosts
有没有办法做到这一点,也就是说,使用两个不同的查询会更快(更少的资源)吗?
答案 0 :(得分:3)
假设ranks
中只有一列你想要,你可以使用相关的子查询来做到这一点:
SELECT u.*,
(select r.minPosts
from ranks r
where r.minPosts <= u.PostCount
order by minPosts desc
limit 1
) as minPosts
FROM users u;
如果您需要ranks
的整行,请将其加入:
SELECT ur.*, r.*
FROM (SELECT u.*,
(select r.minPosts
from ranks r
where r.minPosts <= u.PostCount
order by minPosts desc
limit 1
) as minPosts
FROM users u
) ur join
ranks r
on ur.minPosts = r.minPosts;
(*
是为了方便;您应该列出您想要的列。)
答案 1 :(得分:2)
因为您正在使用mysql,所以这将起作用:
SELECT * FROM (
SELECT *, users.id user_id
FROM users
LEFT JOIN ranks ON ranks.minPosts <= users.postCount
ORDER BY ranks.minPosts DESC
) x
GROUP BY user_id
Mysql始终返回为每个唯一组遇到的第一个行,因此如果您首先订购数据,则然后使用非标准分组行为,你会得到你想要的行。
虽然这在实践中可靠地运行,mysql documentation说不依赖它。如果您使用这种方便的方法(它可以可靠地传递您可以编写的任何测试),您应该考虑mysql不推荐它,并且以后的mysql版本可能不会以这种方式继续运行。
答案 2 :(得分:0)
我们真正想做的是在群组之前按ranks.minPosts
排序。不幸的是,MySQL不支持使用某种形式的子查询。
如果排名已按其ID排序,则您可以通过选择MAX(ranks.id)
来提取ID,如果不是,则通过选择{{1}仍然可以获得最高ranks.minPosts
}。但是,能够获得整个记录会很高兴。我猜你留下了子查询解决方案,如下所示:
MAX(ranks.minPosts)