我可以运行任何SQL,并将结果作为列的哈希值,或者更确切地说a set of Postgres tuples(包含每个元组的哈希值)。
我不确定如何使用Postgres结果集,特别是以类似于Ruby的惯用方式。
这是我的代码:
sql = "select status, count(*) from batch_details where batch_id = 950 group by status"
status_counts = ActiveRecord::Base.connection.execute(sql)
我必须迭代结果集并按名称访问每个元素:
status_counts.each do |st|
puts st
puts st['count']
end
{"status"=>"new", "count"=>"2"}
2
{"status"=>"ready", "count"=>"23"}
23
{"status"=>"processing", "count"=>"177"}
177
{"status"=>"complete", "count"=>"50"}
50
{"status"=>"error", "count"=>"50"}
50
无法将结果集转换为哈希数组:
2.1.1 :031 > arr = status_counts.to_array
NoMethodError: undefined method `to_array' for #<PG::Result:0x000000097f17b0>
尝试将结果集转换为哈希哈希值时也是如此:
2.1.1 :032 > hsh = status_counts.to_hash
NoMethodError: undefined method `to_hash' for #<PG::Result:0x000000097f17b0>
我想:
使用上面的哈希,我想排除&#39; new&#39;和&#39;准备好&#39;状态并将其余部分加起来然后除以总数:
(177 + 50 + 50 / 2 + 23 + 177 + 50 + 50) * 100
到目前为止我的代码:
status_counts.each {|st| total += st['count'].to_i} => works
但它不起作用:
status_counts.each do |st|
['processing','complete','error'].include? st['status'] do
total2 += st['count'].to_i
end
end
pct = total2/total * 100
答案 0 :(得分:2)
也许这样的事情?:
status_counts.
select { |tuple| %w(processing complete error).include?(tuple['status']) }.
inject(0) { |memo, tuple| memo += tuple['count'].to_i }
第一步过滤结果集以获得所需的元组;第二步总结了所选元组的计数。 PGResult在Enumerable中混合,因此它应该与select / inject一起使用。
答案 1 :(得分:0)
对于我自己的问题不是一个确切的答案,但对于试图迭代Postgres结果集的任何人来说都是有用的信息:
sql = "update batch_details set status = 'processing' " +
"where status in ('ready','processing','failed') " +
"and batch_id = #{batch_id} " +
"returning id"
batch_detail_ids = []
res = ActiveRecord::Base.connection.execute(sql)
# TODO needs some error checking
res.each{|tuple| batch_detail_ids << tuple['id'].to_i}