【问题标题】:Selecting records according to date in MySQL在 MySQL 中根据日期选择记录
【发布时间】:2013-10-02 23:42:43
【问题描述】:

我有两张表——我们称它们为gradetest——它们的信息通过第三张表上的键相关联,我们称之为student

如果test 包含列student_idtest_topictest_date,并且grade 包含列student_idgradeentered_date,我希望能够查看grade 表中的记录,并根据student_identered_date,仅将其与test 中具有相同student_id 且日期最近的记录关联。

我当前的查询似乎返回了与所有以前的测试相关的每个成绩,而不是只返回最近的一个。我不知道如何限制它,以便它只显示每个成绩与输入成绩时的最新测试相匹配。

我认为我没有很好地解释这一点,因此我在此处设置了一个带有示例架构、一些测试数据和我当前查询的 SQL Fiddle:http://sqlfiddle.com/#!2/b5233/5

预计到达时间: 澄清一下:我希望查询能够报告每个考试的成绩,该成绩是通过最近参加的考试推导出来的在输入成绩时。我在这里添加了一个新的变体小提琴:http://sqlfiddle.com/#!2/b5233/43,其中包含一个包含测试主题的查询,我认为这使问题更加清晰。对于 'Adam' (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

但目前你会看到它返回的是成绩表中的每个成绩与之前进行的所有测试相匹配,而不仅仅是最近的。

【问题讨论】:

  • 你试过 GROUP BY student_id 吗?
  • 我有,但我承认我无法理解 GROUP BY 的工作原理。最终,它似乎只为给定学生返回一条记录,而不是为他们参加的每次测试返回一条记录。
  • 您是否尝试通过测试获得所有学生的最新成绩,每个学生(或您限制在小提琴上的单个学生)?
  • 这是个好问题。最终,我想从这个选择中构建一个视图,所以实际上我希望它是每个学生、每个学生的所有最新测试成绩,但在我的测试中,我只是将其限制为一个学生,以便更容易查看它是否按预期工作。
  • 每个测试行对应一个成绩行吗?或者,一个考试可以有多个等级吗?或者一个年级有多个测试?

标签: mysql join comparison timestamp


【解决方案1】:

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

这将使您能够直接将成绩与特定学生的考试联系起来。

【讨论】:

  • 我也在想同样的事情
  • 诚然,这个例子的部分弱点是我试图使它比我真正试图解决的问题更通用,唉。无论如何,在成绩表中创建 test_id FK 的架构更改不是一个选项,即使我知道这将是理想的。
【解决方案2】:

架构已关闭 - 您可能已经知道。应该有一种方法可以将成绩与测试 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低于下一次测试的时间无法找到以后的考试日期

来,拉小提琴:http://sqlfiddle.com/#!2/7c069f/9/0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-17
    • 2012-10-04
    相关资源
    最近更新 更多