我有一个极端的情况,我想只在执行SQL查询之后使用.first
。
我的情况是下一个:
User.select("sum((type = 'foo')::int) as foo_count",
"sum((type = 'bar')::int) as bar_count")
.first
.yield_self { |r| r.bar_count / r.foo_count.to_f }
但是,这将引发SQL错误,提示我应在GROUP BY
子句中包含我的user_id。我已经找到了使用to_a
的骇客解决方案,但是我真的很想知道在调用.first
之前是否有适当的方法来强制执行。
答案 0 :(得分:1)
该错误是因为first
使用order by语句来按id
进行排序。
“查找第一个记录(如果提供了参数,则查找第N个记录)。如果未定义顺序,它将通过主键进行排序。”
代替尝试take
“给出一条记录(如果提供了参数,则提供N条记录),而没有任何隐含的顺序。该顺序将取决于数据库的实现。如果提供了顺序,则将予以遵守。”
所以
User.select("sum((type = 'foo')::int) as foo_count",
"sum((type = 'bar')::int) as bar_count")
.take
.yield_self { |r| r.bar_count / r.foo_count.to_f }
应该正常工作,但是如前所述,顺序不确定。
答案 1 :(得分:1)
您可能想使用pluck
而不是select
来检索数据,https://www.datastax.com/dev/blog/lightweight-transactions-in-cassandra-2-0只是更改将哪些字段加载到 models 中:
User.pluck(
"sum((type = 'foo')::int) as foo_count",
"sum((type = 'bar')::int) as bar_count"
).map do |foo_count, bar_count|
bar_count / foo_count.to_f
end
如有必要,您也可以在查询中进行除法。