2011-10-07 61 views
1

我在做一個rails應用程序。我必須做一個比較引擎有點複雜。我正在嘗試做一個原型。我的查詢可能差異很大,所以我必須使用很多範圍,但這不是我的問題。activerecord中的複雜子查詢

我的查詢必須比較候選人。這些考生已經回答了一些考試。這些測試屬於類別。這些測試有不同的最大值,我必須能夠按類別比較候選人。

所以我必須計算好答案的百分比。我必須能夠比較一個類別中所有可能用例的候選人。所以,我必須能夠比較所有這個類別的平均答案率。

簡而言之:我必須能夠使用子查詢來比較一些候選人。我必須能夠比較他們的測試或類別。我的問題是使用一個子查詢能夠爲一個候選人可能通過的所有測試返回一個好的回答率。

而且我必須能夠在order_by或having子句中使用此子查詢。

我該如何構造這個子查詢?我沒有問題處理複雜的條件查詢與一些範圍。這必須是一個真正的子查詢,因爲我在這裏使用6或7個模型。

我要求一個活躍的記錄方式,因爲這必須與任何由rails支持的數據庫一起工作。

對不起,我的英語不好。

編輯:

一個例子是值得1000個字怎麼可能做這樣的事情:

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

這個例子是愚蠢的,OK。那麼,是否有可能做到這樣的事情?

編輯2:

我看到了一些關於AREL的文章。我想知道是否可以在沒有第三方插件的情況下做到這一點。

是否有可能在子查詢中使用arel做一些子查詢?因爲例如,我每次測試的點數是他所有問題的總和。 (可悲,但我必須保留它)。我需要這個,所以我的子查詢可以計算出我的好答案%。

所以你明白了。這是一件非常強大的事情,所以我需要一些強大的功能,而不是太容易出錯。

編輯3:我取得了一些進展,但我不能在一段時間後發佈答案。

似乎有可能得到這個工作沒有任何插件。我在建築一些成功的一些子查詢是這樣的:

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)) 

這只是個愚蠢的例子,以獲得與3的ID此代碼工作的對象,而不是如我所料。

看到,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 

因此,積極的記錄引用了subreust爲安全目的。這更接近我的願望,但並不是我想要的。

這不起作用

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 

但我覺得這是醜陋的。我將嘗試讓這些子查詢以更加動態的方式工作。我的意思是用列名替換整數值。

+0

爲什麼不創建一個單獨的模型/表結果統計? – Bohdan

+0

目前,我只是想找到計算,所以表現目前不是我主要關心的。我試圖在一個查詢中得到他的工作,因爲我有很多用例。我必須能夠比較java類別中的foo和bar,或者前十名java。在同一屏幕上。所以,我必須能夠在一個請求中做到這一點。因爲,我可能有數百名候選人或一堆。所以我必須使用真正的子查詢。 – Perello

回答

0

我沒有這個問題的確切答案,因爲我不再在同一個企業工作。但解決這個問題的方法是使用group_by子句。所以這個請求變得非常簡單。

有了group_by,我能夠輕鬆操作,分類或者技術。