2012-03-19 88 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