Rails 关于 ActiveRecord 中 where 和 find_by 查询接口的查询方式!!!

qq2729877005 · 2017年08月12日 · 最后由 martin91 回复于 2017年08月12日 · 908 次阅读

如题,先上背景

# User 模型
User.where(state: 5).last
User.find_bystate: 5)

现在我想在 users 表中找到 state 为 5 的最后一个用户,因此我采用 where 查询接口,先找到全部 state 为 5 的 user,再取最后一个,但这样的话,感觉效率不高。因此我想采用类似 find_by 的方式查找,可采用这种方式的话,却有只能找到 users 表中最前面的 state 为 5 的用户,恰恰相反,请问各位前辈有什么解决方法传授小弟,小弟感激不尽😂 😂

共收到 13 条回复
User.order(id: :desc).find_by(state: 5)

这贴暴露了楼主 SQL 基础薄弱,到终端看看这三条语句生成的 SQL 有什么不同。

2楼 已删除
Rei 回复

我的 SQL 的基础确实很薄弱,现在正在菜鸟教程恶补 SQL 基础😂 ,希望谅解一下

User.order(id: :desc).find_by(state: 5)
User.where(state: 5).last

这两条语句生成的 SQL 我仔细看了下,一模一样😶 ,并不能解决问题

User.where(state: 5).last

这个查询生成的 SQL 只会查询一条记录,并不会把所有记录都读出来再拿最后一条。

Rei 回复

我有点不能理解这个说法,我们这样拆开分析看看

User.where(state: 5).last
# 拆开
users = User.where(state: 5)
user = users.last

这样拆是没问题的 那么现在它不是先把所有记录都读出来再拿最后一条吗???

6楼 已删除
qq2729877005 回复

延迟执行,ActiveRecord Query 只有在取值的时候才真正执行,所以在终端里拆开执行是不等价的,因为打印的时候取值了。

Rei 回复
User.where(state: 5).last

在执行这条语句时,不是必须先判断 users 表中 state = 5 的这种情况吗?不先进行这种判断,怎么能执行 last 方法???

Rei 回复

而不取 user 表中 state 的值的话,怎么进行判断?

qq2729877005 回复

都叫你看 SQL 了。

Rei 回复

哦,谢谢答疑

不是。SQL语句会告诉你全部。User.where(state: 5).last 数据库只查了一条记录,只取了一条记录。在rails c里的执行和真正代码中的执行是不一样的,rails c 中执行你拆开的那两句就是取了全部再去最后一条,因为在rails c中会打印取值,就没有延迟执行了。在真正的代码环境会有延迟执行

pathbox 回复

恩恩,谢谢了

首先得有个排序规则 然后再取数据

@qq2729877005 你试试执行

users = User.where(state: 5);nil     # 返回值是 nil,不需要取 users 的值,延迟了 SQL query 执行
user = users.last

users = User.where(state: 5)          # 返回值是 User.where(state: 5),必须取值
user = users.last

有没有什么不同

qq2729877005 关闭了讨论 06月29日 14:33
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册