从表中选择最新的带时间戳的值,该表对于一个列 id 有多个条目,对于每个唯一的列 id 和来自另一个表的数据

Posted

技术标签:

【中文标题】从表中选择最新的带时间戳的值,该表对于一个列 id 有多个条目,对于每个唯一的列 id 和来自另一个表的数据【英文标题】:Select latest timestamped value from table, which has multiple entries for a column id, for each unique column id and data from another table 【发布时间】:2020-09-24 23:31:29 【问题描述】:

我需要从一个学校网站的两个表中提取数据。用户标记(tFlag)他们已经研究并准备回答问题的主题。这些选择记录在 userTopics 表中。有 55 个主题 (topicID),网站上的每个主题都有许多可用的问题 (qID)。

UserTopics 表还列出了每个主题的绩效滚动评级,即 topicScore。每个 topicID 的任何用户都只会有一个唯一的行。

用户主题

| ID | userID | topicID | tFlag | topicScore |
| 25 | 1      | 1       | 1     | 25         |
| 29 | 1      | 2       | 1     | 70         |
| 42 | 1      | 3       | 0     | 5          |
| 41 | 1      | 5       | 0     | 5          |
| 35 | 1      | 6       | 1     | 43         |
| 31 | 1      | 7       | 1     | 62         |
| 44 | 1      | 8       | 0     | 0          |
| 32 | 1      | 9       | 0     | 5          |
| 35 | 1      | 12      | 1     | 30         |

Results 表记录每个回答问题的结果,并为回答时间加上时间戳,因此该表可以为用户回答的每个问题提供许多记录,看起来像这样(其他列已删除)

结果

| resultID | userID | topicID | qID | correct | answerTime          |
| 9        | 1      | 12      | 15  | 1       | 2020-05-28 11:29:18 |
| 10       | 1      | 12      | 26  | 1       | 2020-05-28 11:30:18 |
| 11       | 1      | 1       | 132 | 0       | 2020-06-02 17:03:42 |
| 13       | 1      | 2       | 50  | 0       | 2020-06-02 17:02:53 |
| 14       | 1      | 7       | 10  | 1       | 2020-06-02 17:05:15 |
| 76       | 1      | 6       | 9   | NULL    | 0000-00-00 00:00:00 |
| 75       | 1      | 6       | 9   | NULL    | 0000-00-00 00:00:00 |
| 65       | 1      | 9       | 12  | NULL    | 0000-00-00 00:00:00 |
| 66       | 1      | 9       | 12  | 1       | 2020-06-04 07:34:02 |

为了让系统自动为学生分配问题,我们需要特定用户当前正在学习的每个 topicID 的 topicScore 和 answerTime 值。必须为 UserTopics 表中的每个 topicID 返回一行,其中用户的 tFlag = 1。然后应该从结果表中获取从 userTopics 返回的每个 topicID 的最新 answerTime。但是,如果为特定 topicID 列出的唯一 answerTime 是 0000-00-00 00:00:00,我需要返回它。 (answerTime col 使用 ON UPDATE CURRENT_TIMESTAMP,所以如果他们已经加载了问题但没有回答它,这里的值是零。)

userID = 1 的查询结果希望是:

查询结果

| topicID | topicScore | answerTime          |
| 1       | 25         | 2020-06-02 17:03:42 |
| 2       | 70         | 2020-06-02 17:02:53 |
| 6       | 43         | 0000-00-00 00:00:00 |
| 7       | 62         | 2020-06-02 17:05:15 |
| 12      | 30         | 2020-06-04 07:34:02 |

我已经尝试了以下查询,但它没有得到我想要的,也没有真正理解它,因为我对 mysql 的掌握有点基本 atm。 (另一个人写的查询)

SELECT
    r.userID,
    r.topicID,
    r.answerTime,
   (SELECT t.topicScore FROM UserTopics t WHERE t.userID = r.userID AND t.topicID = r.topicID) AS topicScore
    FROM Results r
    LEFT JOIN Results r2 ON r2.topicID = r.topicID AND r.answerTime < r2.answerTime
    WHERE r2.answerTime IS NULL AND r.userID = 1 
    ORDER BY `r`.`topicID` ASC

我可以看到它需要在某处有 Where t.tFlag =1,但是当我将它放在方括号中的 where 子句中时,它也不起作用,所以我假设整个查询需要重写。很高兴得到任何帮助。

【问题讨论】:

见meta.***.com/questions/333952/… 【参考方案1】:

这是我现在按照以下 O Jones 建议尝试和测试的查询....需要进行一些更改,但核心正是医生所要求的,就像一个魅力一样,谢谢。每个查询只需要一个 userID,并且只需要 topicScores 不为 0 的结果。此外,由于 UserTopics 表中每个 topicID 只有一行,因此也不需要 MAX 语句。

SELECT ut.topicId, 
       ut.topicScore,
       MAX(r.answerTime) answerTime
  FROM UserTopics ut
  LEFT JOIN Results r   ON ut.userId = r.userId
                       AND ut.topicId = r.topicId
WHERE ut.tFlag =1 AND ut.userId = 1 AND ut.topicScore >0
GROUP BY ut.topicId 
ORDER BY ut.topicId

【讨论】:

【参考方案2】:

首先,使用零日期戳会使设计变得脆弱。更高版本的 MySQL 不允许零日期戳。您需要发出此命令才能使事情正常进行,即删除NO_ZERO_DATE 模式。

SET sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';

您最好使用 NULL 而不是零日期戳。话说……

这是GROUP BY 的工作,您可以从中提取 userId 和 topicId 的每个组合的最高分数和 answerTime。 (https://www.db-fiddle.com/f/swC1jG2mMHRsAkCouJNfXq/5)

SELECT ut.userId, ut.topicId, 
       MAX(ut.topicScore) topicScore, 
       MAX(r.answerTime) answerTime
  FROM UserTopics ut
  LEFT JOIN Results r   ON ut.userId = r.userId
                       AND ut.topicId = r.topicId
WHERE ut.tFlag =1
GROUP BY ut.userId, ut.topicId 
ORDER BY ut.userId, ut.topicId

【讨论】:

将与您的建议一起使用 NULL 而不是零时间戳谢谢。我已经修改了您的答案以解决几个问题,因为我只想要每个查询的一个用户 ID 的一组结果,并且只需要 topicScore 不为零的 topicID。我已将调整后的查询放在下面的答案中,但您已经破解了 O Jones 先生!非常感谢。

以上是关于从表中选择最新的带时间戳的值,该表对于一个列 id 有多个条目,对于每个唯一的列 id 和来自另一个表的数据的主要内容,如果未能解决你的问题,请参考以下文章

如何从表中提取行,用不同的值过滤同一列?

从表和参考表中选择列、count(id)

MYSQL 根据多行从表中选择

mysql选择组中的最新时间戳

Sqlite:从表中选择 * 但 id

PostgreSQL ,从 2 个表中选择,但仅从表 2 中选择最新的元素