【发布时间】:2015-04-02 09:18:42
【问题描述】:
我正在研究 Ruby on Rails,并且有一些关于 Rails 活动记录及其 SQL 转换的具体问题。
仅供参考,我使用的是 postgresql,而 user 模型有许多 statuses,我想根据 订购 users statuses 的 created_at 列。虽然我找到了解决方案,User.includes(:statuses).order('statuses.created_at desc'),但我仍然有一些(可能是相互关联的)我不太了解的东西。
1) 在 Rails 控制台上,(为了更好的可读性,我进行了简化)
User.joins(:statuses).to_sql 产生"SELECT users.* FROM users INNER JOIN statuses ON statuses.user_id = users.id"。
User.includes(:statuses).references(:statuses).to_sql 产生"SELECT users.id AS t0_r0, ...(simplified)... statuses.created_at AS t1_r3 FROM users LEFT OUTER JOIN statuses ON statuses.user_id = users.id"
选择 users.* 和选择每个单独的列有什么区别?
2) 也在 Rails 控制台上,
User.joins(:statuses).size 产生SELECT COUNT(*) FROM users INNER JOIN statuses ON statuses.user_id = users.id => 155。
User.includes(:statuses).references(:statuses).size 产生SELECT COUNT(DISTINCT users.id) FROM users LEFT OUTER JOIN statuses ON statuses.user_id = users.id => 16。
为什么 includes 自动包含 distinct 子句而 joins 不包含?
3) 我试图获得由 statuses.created_at 排序的不同 users,并在 users 上加入了 statuses .
我使用了这个子句:User.joins(:statuses).select('users.*, statuses.created_at').order('statuses.created_at desc').distinct。 (由于PG::InvalidColumnReference: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list,我应该使用select statuses.created_at)
但是这个子句并没有删除重复!虽然User.joins(:statuses).select!('users.*, statuses.created_at').order('statuses.created_at desc').distinct.size 产生了16,但当我实际执行它时,我看到了很多重复。
生成SQL语句:SELECT DISTINCT users.*, statuses.created_at FROM users INNER JOIN statuses ON statuses.user_id = users.id ORDER BY statuses.created_at desc,并显示如下图。
如您所见,它显示了我的记录的重复。
所以我的第三个问题是,为什么 distinct 子句不删除重复项(以及为什么 size 显示不同的结果)?
提前谢谢你!
【问题讨论】:
标签: ruby-on-rails postgresql join include distinct