2013-10-02 43 views
3

我有两个表 - 我们将其称为gradetest - 通过第三个表上的关键字相关的信息,我们将其称为student在MySQL中根据日期选择记录

如果test包含test_topicstudent_id,和test_dategrade包含列student_idgradeentered_date,我希望能够看到一个记录在grade表的基础上,student_identered_date,副教授它仅与test中的记录相同,其日期最近为student_id

我目前的查询似乎会返回与所有以前的测试相关的每个年级,而不仅仅是最近的一次。我无法弄清楚如何限制它,以便显示每个等级只与进入等级时最近的测试相匹配。

我不认为我已经解释了这个非常好,所以我给自己定了一个SQL拨弄示例模式,一些测试数据,以及我的当前查询的位置:http://sqlfiddle.com/#!2/b5233/5

ETA:澄清:我希望查询报告的等级为,每个测试都是通过最近进入等级时进行的测试推导的。我在这里添加了一个新的变体小提琴:http://sqlfiddle.com/#!2/b5233/43,其中包含测试主题,我认为这个问题会让问题更清楚一些。对于“亚当”(student_id数据= 1)所期望的结果将是:

STUDENT_ID     TEST_DATE      TEST_TOPIC      GRADE_TIME    TEST_GRADE 
    1   October, 02 2013 23:08:24+0000   Medieval History   October, 02 2013 23:08:25+0000   A 
    1   October, 02 2013 23:08:30+0000   Calculus     October, 02 2013 23:08:32+0000   C 
    1   October, 02 2013 23:08:43+0000   Biochemistry    October, 02 2013 23:08:44+0000   A 
    1   October, 02 2013 23:08:49+0000   Advanced German   October, 02 2013 23:08:50+0000   C 

,但目前你会看到什么还给是打击匹配等级表中的每个年级之前,与其采取一切测试只有最近的。

+0

你试过GROUP BY student_id吗? – Gustavo

+0

我有,但我承认我无法理解GROUP BY的工作原理。最终,它似乎只为给定的学生返回一个记录,而不是为每次测试返回一个记录。 – Valentine

+0

你是否试图通过考试,每个学生(或一名学生,因为你已经限制了小提琴)获得所有最新成绩? – leon

回答

2

我认为你应该在你的成绩表中有一个test_id外键,这样你就不必尝试加入会导致你问题的复杂日期值(例如,如果学生需要多个测试在给定的日期)。

这会给你一个手段,直接关系到特定学生的考试成绩。

+0

我在想同一件事 –

+0

这个例子的弱点部分是我试图让它比我真正想解决的问题更通用,唉。在任何情况下,尽管我意识到这将是理想的,但在等级表中制作test_id FK的模式更改不是一种选择。 – Valentine

0

模式已关闭 - 您可能已经知道了。应该有一种方法可以直接将评分与测试ID相关联。否则,类似这样的东西可以工作(尽管我认为数据库过于庞大,而且表格上的行数很多,不能表现出性能)。

SELECT 
    S.student_id, 
    S.student_name AS Student, 
    T.test_topic AS Topic, 
    G.grade AS Grade, 
    T.test_date AS `Test Date`, 
    G.entered_date AS `Grade Time (debug)` 
FROM 
    student S, test T, grade G 
WHERE 
    S.student_id = G.student_id 
    AND S.student_id = T.student_id 
    AND G.entered_date > T.test_date 
    AND T.test_date = 
    (
    SELECT MAX(T2.test_date) 
    FROM test T2 
    WHERE T2.student_id = T.student_id 
    AND T2.test_topic = T.test_topic 
) 
    AND 
    (
    G.entered_date < 
     (
     SELECT MIN(T3.test_date) 
     FROM test T3 
     WHERE T3.student_id = T.student_id 
     AND T3.test_topic <> T.test_topic 
     AND T3.test_date > T.test_date 
    ) 
    OR NOT EXISTS 
     (
     SELECT 1 
     FROM test T4 
     WHERE T4.student_id = T.student_id 
     AND T4.test_topic <> T.test_topic 
     AND T4.test_date > T.test_date 
    ) 
    ) 
ORDER BY S.student_id, T.test_date, G.entered_date 

上面的查询获取一个主题和学生最新的测试,然后进行到发现的行,随着年级为学生最高entered_date比下一次测试的时间 OR 较低的匹配其中不迟可以发现测试日期

在这里,有一个小提琴:http://sqlfiddle.com/#!2/7c069f/9/0