代码之家  ›  专栏  ›  技术社区  ›  pjb3

如何使用ActiveRecord获取查询结果中的行和列?

  •  1
  • pjb3  · 技术社区  · 15 年前

    ActiveRecord是否可以执行自定义SQL查询并让它返回一个数组,其中第一行是列名,下面每一行是行数据?我想执行如下操作:

    connection.select_rows_with_headers "SELECT id, concat(first_name, ' ', last_name) as name, email FROM users"
    

    并让它返回:

    [["id","name","email"],["1","Bob Johnson","bob@example.com"],["2","Joe Smith","joe@example.com"]]
    

    这将允许我在如下HTML表中打印自定义查询的结果:

    <table>
      <% result.each_with_index do |r,i| %>
        <tr>
          <% r.each do |c| %>
            <% if i == 0 %>
              <th><%=h c %></th>
            <% else %>
              <td><%=h c %></td>
            <% end %> 
          <% end %>
        </tr>
      <% end %>
    </table>
    

    注意 select_all 不起作用,因为每个哈希中的键都是无序的,所以您已经丢失了查询中指定的结果顺序。

    1 回复  |  直到 15 年前
        1
  •  2
  •   fowlduck    15 年前

    不完全是你想要的,但可能是:

    connection.execute('select * from users').all_hashes
    

    你会回来的

    [{:id => 1, :name => 'Bob', :email => 'bob@example.com'},{:id => 1, :name => 'Joe', :email => 'joe@example.com'}]
    

    你可以这样做:

    results = connection.execute('select * from users').all_hashes
    munged_results = []
    columns = results.first.keys.map(&:to_s)
    munged_results << results.first.keys.map(&:to_s)
    munged_results += results.map{|r| columns.map{|c| r[c]} }
    

    像那样的

    编辑:

    results = connection.execute('select * from users').all_hashes
    munged_results = []
    columns = User.column_names
    munged_results << columns
    munged_results += results.map{|r| columns.map{|c| r[c]} }
    

    那应该是适当订购的。

    除此之外,还有从execute返回的result对象,可以对其进行询问以获取信息位。类似于fetch撊fields的方法按顺序获取字段,而fetch撊row将结果集的每一行作为数组获取(类似于迭代器)。

    再次编辑:

    好的,这里有一个很好的解决方案,可以修改您使用的任何数据库:

    class Mysql::Result
      def all_arrays
        results = []
        results << fetch_fields.map{|f| f.name}
    
        while r = fetch_row
          results << r
        end
    
        results
      end
    end
    

    这样就不用花一吨的开销了。

    这样使用:

    connection.execute('select salt, id from users').all_arrays