2012-03-19 110 views
0

我試圖從幾張表中獲取一些統計數據。我們有一個用戶表,測驗表,測驗問題集表和測驗問題表。每個測驗都有很多組,每組有一個或多個問題。還有一個問題表,這是問題的來源(測驗問題表將問題鏈接到問題集,然後鏈接到測驗,然後鏈接到用戶)。我需要的是看到正確回答的問題數量以及回答的問題數量,但僅限於過去的50個問題。所以如果一個用戶回答了120個問題,那麼只有最近的50個用在這個查詢中;如果用戶回答了37個問題,則應該使用他們的所有問題。我希望得到這個佈局,以便user_id,questions_answered,questions_answered_correctly。我目前有這個工作,但我正在瀏覽每個用戶,並抓住他們最近的50個問題,並附上一些限制組織參與的附加表格,我必須做數百次,如果不是數千次,才能得到一份統計報告。有限子查詢的MySQL查詢

我猜我需要做一個子查詢的地方只拉最近的問題從用戶,但我不知道這樣的子查詢如何工作。這是迄今爲止我所擁有的,但我確信我完全沒有這個。它執行,但不正確。有些結果是超過50級的時候,他們不應該:

SELECT users.id, (SELECT COUNT(grammar_quiz_questions.id) FROM `grammar_quiz_questions` 
INNER JOIN `grammar_quiz_question_sets` ON `grammar_quiz_question_sets`.`id` = `grammar_quiz_questions`.`grammar_quiz_question_set_id` 
INNER JOIN `grammar_quizzes` ON `grammar_quizzes`.`id` = `grammar_quiz_question_sets`.`grammar_quiz_id` 
INNER JOIN `grammar_questions` ON `grammar_questions`.`id` = `grammar_quiz_questions`.`grammar_question_id` 
WHERE (grammar_quiz_questions.finished is not null AND grammar_quizzes.user_id = users.id) 
ORDER BY grammar_quiz_questions.finished DESC LIMIT 50) AS `questions_answered`, (SELECT COUNT(grammar_quiz_questions.id) FROM `grammar_quiz_questions` 
INNER JOIN `grammar_quiz_question_sets` ON `grammar_quiz_question_sets`.`id` = `grammar_quiz_questions`.`grammar_quiz_question_set_id` 
INNER JOIN `grammar_quizzes` ON `grammar_quizzes`.`id` = `grammar_quiz_question_sets`.`grammar_quiz_id` 
INNER JOIN `grammar_questions` ON `grammar_questions`.`id` = `grammar_quiz_questions`.`grammar_question_id` 
WHERE (grammar_quiz_questions.finished is not null AND grammar_quizzes.user_id = users.id AND grammar_quiz_question_sets.correct_on_first_attempt = 1) 
ORDER BY grammar_quiz_questions.finished DESC LIMIT 50) AS `questions_answered_correctly` 
FROM users 

謝謝, 詹姆斯

回答

1

UPDATE:

下面的更新是不是一個完整的回答這個問題,但一些蹭。我不知道你爲什麼要查詢所有這些表格。 grammar_quiz_question_sets是grammar_quiz_questions的互斥子集嗎?怎麼樣的grammar_quizzes和grammar_questions,什麼是集合關係?鑑於我不知道這些答案,但是您應該看看下面的代碼片段。我希望它會引導您:

set @correct:=0; 
select users.id, count(p.id), sum(if(r.correct_on_first_attempt = 1,1,0)) as correct 
from grammar_quiz_questions p, grammar_quiz_question_sets r, users; 

ORIGINAL:

我想象你有一個控制,並通過這些記錄的添加和操縱數據訪問層(Java,PHP,Python和等)。此外,我想你需要在用戶的生命週期中不止一次地獲取統計信息。因此,儘管您可能需要像您一樣的查詢來重新校準一次 - 如果這將是必要的 - ,您需要的東西不那麼令人興奮。因此提出以下建議。

1]創建一個統計表格:

create table statistics(
    user_id int(11) not null, -- foreign key 
    questions_answered int(11) not null default 0, 
    questions_answered_correctly int(11) no null default 0 
    -- for primary key, you may use user_id or some auto record_id 
) 

2]第一次,運行 「重/行政」 查詢

3]隨後,更新用戶的統計每次測驗後或每個回答的問題。這裏的想法是,你將在內存中(即在你的編程層)獲得這些信息,因爲你必須更新測驗表;在那段時間做一些數學更新統計表。例如想象的java:

public void updateStats(int userId, int questions, int correct){ 
    String query = 
    "insert into statistics(user_id,questions_answered,questions_answered_correctly) "+ 
    "values("+userId+", "+questions+", "+correct+") "+ 
    "on duplicate key update "+ 
    "questions_answered=questions_answered+values(questions_answered), "+ 
    "questions_answered_correctly = questions_answered_correctly + values(questions_answered_correctly)"; 
    ... //execute the statement 

}

現在

爲「重」的查詢,我下面有一點更加清楚,也鼓勵其他人改寫它採取刺傷它:

SELECT users.id, 
(
SELECT COUNT(p.id) 
FROM grammar_quiz_questions p, grammar_quiz_question_sets r, grammar_quizzes t, grammar_questions u 
WHERE r.id = p.grammar_quiz_question_set_id 
    AND t.id = r.grammar_quiz_id 
    AND u.id = p.grammar_question_id 
    AND p.finished is not null 
    AND t.user_id = users.id 
ORDER BY p.finished DESC LIMIT 50 
) AS questions_answered, 
(
SELECT COUNT(p.id) 
FROM grammar_quiz_questions p, grammar_quiz_question_sets r, grammar_quizzes t, grammar_questions u 
WHERE r.id = p.grammar_quiz_question_set_id 
    AND t.id = r.grammar_quiz_id 
    AND u.id = p.grammar_question_id 
    AND p.finished is not null 
    AND t.user_id = users.id 
    AND r.correct_on_first_attempt = 1 

ORDER BY p。已完成DESC LIMIT 50 )AS questions_answered_correctly FROM users

+0

我想過了,但統計表必須更復雜。我需要跟蹤何時減少questions_answered_correctly的價值,以及在問題得到解答後何時提出問題。此外,該查詢不起作用的值超過50,正在爲questions_answered和questions_answered_correctly表提供。此外,我在軌道上使用紅寶石。我意識到我可以使用ActiveRecord,但是我在這裏以原始查詢開始。 – 2012-03-20 15:03:16

+1

根據統計表,實際上你必須跟蹤。但你已經這麼做了。想象不得不爲具有數百條記錄的狂熱用戶計算統計數據。您不希望僅因爲數據庫中有一個附加條目而導致您的大量查詢;所以想想stats表。它便宜很多。 – kasavbere 2012-03-20 16:36:44

+0

您是否在grammar_quizzes中爲每個正確的問題獎勵用戶?或者因爲你沒有問題的重疊? – kasavbere 2012-03-20 18:47:56