activerecord中的复杂子查询

时间:2011-10-07 09:59:08

标签: ruby-on-rails-3 activerecord

我正在做一个rails应用程序。我必须做一个有点复杂的比较引擎。我正在尝试做原型。我的查询可以有很大的不同,所以我必须使用很多范围,但这不是我的问题。

我的查询必须比较候选人。这些候选人已经回答了一些测试这些测试属于类别。这些测试具有不同的最大值,我必须能够按类别比较候选人。

所以我必须计算出一定比例的好答案。我必须能够在一个类别中比较所有可能用例中的候选者。所以,我必须能够比较所有这一类别的平均良好答案率。

简而言之:我必须能够使用子查询来比较一些候选人。我必须能够将它们作为测试或类别进行比较。我的问题是使用子查询能够为候选人在类别中传递的所有测试返回一个好的答案率。

我必须能够在order_by或having子句中使用此子查询。

如何构建此子查询?使用某些范围处理复杂的条件查询没有问题。这必须是一个真正的子查询,因为我在这里使用6或7个模型。

我要求一种有效的记录方式,因为这必须适用于rails支持的任何数据库。

请原谅我可怜的英语。

编辑:

一个例子值1000字,所以怎么做这样的事情:

Sessiontest.find(Candidat.where(:firstname => 'toto'))

这个例子很愚蠢,好吧。那么,有可能做这样的事吗?

Edit2:

我看到一些关于AREL的帖子。我想知道是否可以在没有第三方插件的情况下这样做。

是否可以在子查询中使用arel进行一些子查询?因为,例如,我每次测试的积分数是他所有问题的积分之和。 (伤心,但我必须保留它)。我需要这个,所以我的子查询可以计算出我的好答案%。

所以你明白了。这是必须非常强大的东西,所以我需要强大的东西,而不是太容易出错。

Edit3:我取得了一些进展,但我暂时不能回答。

似乎可以在没有任何插件的情况下完成这项工作。我在建筑物中取得了一些成功,如下所示:

 toto = Candidat.where(:lastname => Candidat.select(:lastname).where(:lastname => "ulysse").limit(1))

请求:

Candidat Load (1.0ms)[0m  SELECT "candidats".* FROM "candidats"    WHERE "candidats"."lastname" IN (SELECT "candidats"."id" FROM "candidats" WHERE "candidats"."lastname" = 'ulysse' LIMIT 1

这可以工作并创建一个真正的子查询。我将尝试一些更高级的经验,以达到我真正需要的水平。

刚试过的子子查询也很奇怪。

编辑5:

我正在尝试一些更高级的东西,而且有很多东西,我仍然不明白。

- toto = Candidat.where("id = ? / ? ", Sessiontest.select(:id).where(:id => 6), Sessiontest.select(:id).where(:id => 2))

这只是一个愚蠢的例子,以获取id为3的对象。这段代码有效,但不是我预期的。

参见sql:

1m[35m (1.0ms)[0m  SELECT COUNT("sessiontests"."id") FROM "sessiontests" WHERE "sessiontests"."id" = 6
 [1m[36mSessiontest Load (0.0ms)[0m  [1mSELECT id FROM "sessiontests" WHERE "sessiontests"."id" = 6[0m
 [1m[35m (1.0ms)[0m  SELECT COUNT("sessiontests"."id") FROM "sessiontests" WHERE "sessiontests"."id" = 2
 [1m[36mSessiontest Load (1.0ms)[0m  [1mSELECT id FROM "sessiontests" WHERE "sessiontests"."id" = 2[0m
 [1m[35mCandidat Load (1.0ms)[0m  SELECT "candidats".* FROM "candidats" WHERE (id = 6 / 2)

因此,它不使用子查询。我试过.to_sql。但它以这种方式介绍我的SQL:

1m[36mCandidat Load (0.0ms)[0m  [1mSELECT "candidats".* FROM "candidats" WHERE (id = 'SELECT id FROM "sessiontests" WHERE "sessiontests"."id" = 6' / 2 )[0m

如此活跃的记录引用了子安全用于安全目的。这更接近我的愿望,但不是我想要的。

这不起作用

Candidat.where("id = (?) / ? ", Sessiontest.select(:id).where(:id => 6).to_sql, Sessiontest.select(:id).where(:id => 2))

引号可防止子查询生效。

但是这项工作:

Candidat.where("id = (" + Sessiontest.select(:id).where(:id => 6).to_sql + ") / (" + Sessiontest.select(:id).where(:id => 2).to_sql + ") ")

[1m[36mCandidat Load (1.0ms)[0m  [1mSELECT "candidats".* FROM "candidats" WHERE (id = (SELECT id FROM "sessiontests" WHERE "sessiontests"."id" = 6) / (SELECT id FROM "sessiontests" WHERE "sessiontests"."id" = 2) )[0m

但我觉得这很难看。我将尝试以更动态的方式使这些子查询工作。我的意思是用列名替换整数值。

1 个答案:

答案 0 :(得分:0)

我不再拥有这个问题的确切答案,因为我不再在同一个企业工作了。但是这个问题的解决方案是使用group_by子句。所以请求变得非常简单。

使用group_by,我能够轻松操作,分类或技术。