2011-10-07 2 views
1

난 레일 애플 리케이션을하고 있어요. 나는 약간 복잡한 비교 엔진을해야한다. 나는 현재 프로토 타입을하려고하고있다. 내 쿼리는 매우 다양 할 수 있으므로 많은 범위에서 작업해야하지만 내 문제는 아닙니다.활성 레코드의 복합 서브 쿼리

내 쿼리는 후보를 비교해야합니다. 이 후보자는 몇 가지 테스트에 답했습니다. 이 테스트는 범주에 속합니다. 이 시험은 최대 값이 다르므로 후보를 범주별로 비교할 수 있어야합니다.

그래서 좋은 답변 %를 계산해야합니다. 하나의 범주에서 가능한 모든 유스 케이스에서 후보자를 비교할 수 있어야합니다. 그래서,이 모든 범주에 대한 평균 좋은 응답 속도를 비교할 수 있어야합니다.

요약 : 일부 후보를 비교하기 위해서는 서브 쿼리를 사용할 수 있어야합니다. 나는 그 (것)들을 시험 또는 종류를 위해 비교할 수 있어야한다. 내 문제는 후보자가 범주에서 통과했을 수있는 모든 테스트에 대해 좋은 응답률을 반환 할 수있는 하위 쿼리를 사용하는 것입니다.

그리고이 하위 쿼리를 order_by 또는 having 절에서 사용할 수 있어야합니다.

어떻게이 하위 쿼리를 구성 할 수 있습니까? 어떤 범위에서 복잡한 조건부 쿼리를 처리하는 데 아무 문제가 없습니다. 여기에 6 개 또는 7 개의 모델로 작업하기 때문에 이것은 실제 하위 쿼리 여야합니다.

활성 레코드 방법을 요청합니다. 레일스에서 ​​지원하는 모든 데이터베이스에서 작동해야합니다.

실례합니다.

편집 :

예 가치가 1000 개 단어 때문에이 같은 일을 할 수있는 방법 :

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

이 예는 확인, 바보입니다. 그래서 이런 일을 할 수 있을까요?

편집 2 :

나는 AREL에 관한 게시물을 보았습니다. 제 3 자 플러그인없이이 작업을 수행 할 수 있는지 알고 싶습니다.

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

현재, 나는 계산만을 찾으려고 노력하고 있습니다. 따라서 성능은 현재 내 관심사가 아닙니다. 하나의 쿼리에서 그의 작업을 얻으려고하고 있는데, 실제로 많은 유스 케이스가 있기 때문입니다. 나는 자바 카테고리 또는 상위 10 자바에서 foo와 bar를 비교할 수 있어야한다. 같은 화면에서. 그래서, 나는 하나의 요청으로 이것을 할 수 있어야한다. 왜냐하면 수백 명의 후보자 나 무리가있을 수 있습니다. 그래서 난 진짜 하위 쿼리를 사용해야합니다. – Perello

답변

0

더 이상 같은 엔터프라이즈에서 작동하지 않기 때문에이 질문에 대한 정확한 답변이 없습니다. 그러나이 문제에 대한 해결책은 group_by 절을 사용하는 것이 었습니다. 그래서 요청이 정말 쉬워졌습니다.

group_by를 사용하여 쉽게 카테고리 나 기술을 조작 할 수있었습니다.