2012-04-17 3 views
2

나는 오늘 이전에 질문을하고 잘 작동하는 좋은 응답을 받았습니다. 질문에 두 번째 부분이있어 응답을 얻지 못했고 다시 시도하고 있습니다.mysql complex sql

SELECT q.id,q.question,a.question_id,a.answer, a.correct 
FROM (SELECT * FROM questions q WHERE q.subject_id = 18 
     ORDER BY RAND() LIMIT 5) q 
JOIN answers a on q.id = a.question_id GROUP BY q.id, a.id 

위의 내용은 문제가 없으며 5 개의 임의 질문과 그에 대한 답변이 함께 제공됩니다. 문제는 각 질문에 9 개의 답이 있으며, 그 중 하나는 올바른 (올바른 = 1)이고 다른 것은 잘못된 (올바른 = 0)입니다. 나는 모든 대답을 원하지만 올바른 하나와 다른 3 개의 무작위를 원한다.

나는 몇 시간 동안이 게임을 해왔으며 어디에도 갈 수 없다.

도움을 주시면 감사하겠습니다.

감사

스티브

추신 : 아마 PHP를 통해 처리하는 것이 좋습니다 그러나 다시 잘 모르겠어요. 그것에 관한 어떤 생각도 도움이 될 것입니다.

+0

다른 질문을 시도했지만 실제로 해결할 수 없었습니다. 다른 사람들이 참조하기를 원할 경우를 대비하여 여기까지입니다. http://www.sqlfiddle.com/#!2/34906/34. 어떤 이유로 'answers'에 대한 내부 쿼리의'ORDER BY RAND()'가 작동하지 않습니다. – mellamokb

+1

PHP가 더 좋을 것입니다. MySQL에는 Oracle/SQL Server/PostgreSQL에서 사용할 수있는 언어 구조가 없습니다. – gbn

+0

@gbn : 특히 질문 당 최대 9 개의 답변 만 있기 때문에 동의합니다. 모든 대답을 PHP로 가져 와서 무작위로 처리하는 것도 마찬가지로 쉽습니다. – mellamokb

답변

2

이것은 Y 예에 대한 TOP X 레코드의 또 다른 예입니다. 모든 질문에 대해 4 개의 답을 원합니다. LIMIT은 실제로 두 번 필요합니다 ... 처음에는 자격을 갖춘 질문을 제한하고 "올바른"대답을 보장하는 대답의 또 다른 "순위"는 질문 결과 집합마다 항상 포함됩니다.

내 접근 방식은 질문에 대해 무작위로 우선 적용하여 하위 집합 결과로 얻은 다음이를 답변에 결합하고 Y를 X로 제한합니다. 그러면 우리는 모든 결과를 얻을 수 있습니다. 여기서 중요한 것은 질문 ID로 내부 쿼리를 정렬해야한다는 것입니다 ... 그리고 한정어는 항상 첫 번째 위치에 있지만 이후의 모든 항목은 총 4 개의 레코드가 포함되도록 무작위로 지정됩니다.

그런 다음 최종 쿼리는 WHERE 절을 적용하여 순위 순서가 < = 4 (가능한 모든 9 개의 대답 중 하나의 질문에 포함됨)를 포함하지만 마지막 "ORDER BY"절을 적용하여 질문을 유지합니다 함께,하지만 답변을 무작위로 "올바른"항상 더 이상 항상 첫 번째 위치에 반환됩니다.이 외부 "ORDER BY"절을 테스트 목적으로 제거하여 기능을 확인한 다음 나중에 다시 추가 할 수 있습니다. SQLVars이 과제의 각 :=을 가지고에서

select 
     FinalQA.* 
    from 
     (select 
       QWithAllAnswers.*, 
       @RankSeq := if(@LastQuestion = QWithAllAnswers.id, @RankSeq +1, 1) ARankSeq, 
       @LastQuestion := QWithAllAnswers.id as ignoreIt 
      from 
       (SELECT 
         q.id, 
         q.question, 
         q.RandQuestionResult, 
         a.question_id, 
         a.answer, 
         a.correct 
        FROM 
         (SELECT q.ID, 
           q.Question, 
           q.question_ID, 
           RAND() as RandQuestionResult 
          FROM 
           questions q 
          WHERE 
           q.subject_id = 18 
          ORDER BY RAND() 
          LIMIT 5) JustQ 
         JOIN answers a 
         on q.id = a.question_id 
        ORDER BY 
         JustQ.RandQuestionResult, 
         if(a.correct = 1,0.000000, RAND() 
      ) QWithAllAnswers, 

       (select @RankSeq := 0, @LastQuestion := 0) SQLVars 

    ) FinalQA 

    where 
     FinalQA.ARankSeq < 5 
    order by 
     FinalQA.RandQuestionResult, 
     rand() 

커플 작은 변화 ... 있는지 확인합니다. 원래 게시했을 때 잘못된 오류가 발생했을 수있는 하나의 ":"을 남겼습니다. 또한 "a.correct = 1"(별칭 참조가 없음)을 사용하여 내부 "Order By"를 정규화했습니다. 마지막으로 바깥 쪽 WHERE 절을 <= 4 대신 < 5으로 변경했습니다. 나는 Y 그룹별로 가장 위대한 X 그룹을 많이 만들었고, 그들이 일하는 것을 알고, 확실한 간단한 것을 놓쳤다.

또한 IF() 랜덤 값을 10 진수로 첫 번째 값을 갖도록 조정합니다. 그렇지 않으면 모든 랜덤 스탯이 1 (정수)로 설정되고 절대 절대로 설정되지 않습니다 ... ORDERING이 적용될 때 발생할 수있는 문제에 대해서는 - 모든 Q와 A를 먼저 정렬하여 첫 번째 위치에서 모든 정답을 얻은 다음 해당 세트에 대해 SQLVars을 적용한 다음 순위 순서와 순서를 마무리합니다.

+0

나는 당신의 제안을 시도하고 다음과 같은 오류가 발생했습니다 ... # 1064 - SQL 구문에 오류가 있습니다; 'QWithAllAnswers 근처 QWithAllAnswers.ARankSeq <= 4 order by Q'근처에있는 – SteveF

+0

@ user1292262 라인에있는 올바른 구문을 보려면 MySQL 서버 버전에 해당하는 설명서를 확인하십시오. 개정 된 답변 및 SQL 조정에 대한 의견을 참조하십시오. – DRapp

+0

몇 가지 오타를 수정하고 여기에 솔루션을 구축했습니다. http://www.sqlfiddle.com/#!2/34906/52. 나는 당신이 모델화 한 예를 알고 있으며, 나는 같은 것을 고려했다. 그러나 내가 OP에 대한 논평으로 작성하고 게시 한 자체 솔루션에서와 똑같은 문제가 발생한 것 같습니다. 그것은 이상한 이유 때문에 답을 무작위로 추출하는 것이 아니라 각 질문에서 처음 네 개의 답을 얻는 것입니다. 그래서 기괴한. 어쩌면 sqlfiddle.com 또는 MySQL 버전이 문제가 될 수 있습니까? 나는 직접 테스트 할 수있는 MySQL 인스턴스가 없다 ... – mellamokb

0

당신은 같은 하위 쿼리를 사용하려고 할 수 있습니다 :

(의사)

Select a.*, q.* 
from questions q join answers a on q.id=a.question_id 
where q.id in (SELECT id FROM questions q1 WHERE q1.subject_id = 18 ORDER BY RAND() LIMIT 5) 
and a.id in (SELECT id FROM answers a1 WHERE a1.question_id = q.id ORDER BY a1.correct desc, RAND() LIMIT 4) 

모든 대답을 읽을 더 효과적 일, 랜덤 사람을 선택할 수

(최종 의사) 귀하의 코드에서 (여전히, 주문하실 수 있습니다 correct 내림차순, 알다시피, 하나는 바로 하나입니다). 임의의 순서로 먼저 당신에게 정확한 답을 얻어야한다

SELECT q.id,q.question,a.question_id,a.answer, a.correct 
FROM (SELECT * FROM questions q WHERE q.subject_id = 18 
     ORDER BY RAND() LIMIT 5) q 
JOIN answers a on q.id = a.question_id 
ORDER BY q.id, a.correct, RAND() 

하고 거짓 답변 :

+1

도움을 주셔서 감사합니다. php에서 무작위 화하는 것이 일치 된 것처럼 보입니다. 나는 그것을 줄 것이고, 내가 어떻게하면되는지 알 것이다. 한 번에 모든 질문과 답변을 얻으려는 이유는 질문이 고유해야하므로 한 번에 하나씩 얻을 수 없기 때문입니다. 전체 테스트에서 고유해야합니다. 희망은 그 말이 맞습니다. – SteveF

+1

가장 간단한 솔루션은 실제로 한 쿼리에서 질문을 검색 한 다음 별도의 쿼리에서 각 질문에 대한 대답을 검색하는 것입니다. –

1

이보십시오. 이렇게하면 PHP 코드에서 1 + 3을 쉽게 선택할 수 있습니다.

편집 : 그룹을 삭제하고 대신 한 행의 답을 원하는대로 정렬하십시오.

1

좋은 대답과 임의의 잘못된 대답을 얻기 위해 UNION을 사용하지 않는 이유는 무엇입니까?

SELECT q.id,q.question,a.question_id,a.answer, a.correct 
FROM (SELECT * FROM questions q WHERE q.subject_id = 18 
     ORDER BY RAND() LIMIT 5) q 
    JOIN answers a on q.id = a.question_id 
WHERE a.correct = 0 
GROUP BY q.id, a.id 

UNION 

SELECT q.id,q.question,a.question_id,a.answer, a.correct 
FROM question q 
    JOIN answers a on q.id = a.question_id 
WHERE q.subject_id = 18 
    AND a.correct = 1