将SQL转换为Arel或Squeal

时间:2012-12-08 12:21:23

标签: sql ruby-on-rails activerecord arel squeel

TL;博士

如何将下面的SQL转换为Arel(或Rails中被认为是标准的任何内容)

@toplist = ActiveRecord::Base.connection.execute(
     'select ci.crash_info_id,
        count(distinct(user_guid))[Occurences], 
        c.md5 
      from crashes ci 
        join crash_infos c on c.id=crash_info_id 
      group by ci.crash_info_id
      order by [Occurences] desc')

--- tl结束;博士----

我正在开发一个小型网络项目,它的目标是让我们的客户崩溃报告(当我们的桌面应用程序崩溃时,我们向我们的服务器发送诊断信息),分析它们然后显示导致最常见的错误我们的应用程序崩溃..所以我们专注于修复影响我们用户最大块的错误..

我有两张桌子:

  1. crash_infos - id,md5(.net stacktrace中的堆栈跟踪的md5和异常消息有时会通过.net转换为用户的母语!所以我基本上通过删除特定于语言的部分并生成md5来清理异常它)

  2. 崩溃 - id,user_guid(用户ID),crash_info_id(id到crash_infos表)

  3. 现在问题是,我想创建一个查询,显示唯一用户的最常见崩溃(避免为同一用户计数多次相同的崩溃)并按崩溃次数对其进行排序。不幸的是我不知道Arel(或者轨道上的红宝石),所以我最终得到了原始的SQL :(

    @toplist = ActiveRecord::Base.connection.execute(
      'select ci.crash_info_id,
         count(distinct(user_guid))[Occurences], 
         c.md5 
       from crashes ci 
       join crash_infos c on c.id=crash_info_id 
       group by ci.crash_info_id 
       order by [Occurences] desc')
    

    我怎样才能将此转换为更“鲁莽”的东西?

    提前谢谢

1 个答案:

答案 0 :(得分:2)

不确定这实际上是否更好,但至少你应该有一个独立于数据库的查询...

crashes     = Arel::Table.new(:crashes)
crash_infos = Arel::Table.new(:crash_infos)

crashes.
    project(crashes[:crash_info_id], crash_infos[:md5], Arel::Nodes::Count.new([crashes[:user_guid]], true, "occurences")).
    join(crash_infos).on(crashes[:crash_info_id].eq(crash_infos[:id])).
    group(crashes[:crash_info_id]).
    order("occurences DESC").
    to_sql

给出:

SELECT "crashes"."crash_info_id", "crash_infos"."md5", COUNT(DISTINCT "crashes"."user_guid") AS occurences FROM "crashes" INNER JOIN "crash_infos" ON "crashes"."crash_info_id" = "crash_infos"."id" GROUP BY "crashes"."crash_info_id" ORDER BY occurences DESC