【问题标题】:MySQL Select By Newest TimestampMySQL 按最新时间戳选择
【发布时间】:2012-08-08 09:05:35
【问题描述】:

我在 SO 上看到了一些类似类型的问题,但是,我无法找到针对我的具体问题的解决方案。 (仅供参考,这些不是我真正的专栏,只是一个简短的例子)。

我有一张基本表my_table

user_1 user_2 timestamp note(not part of table)
23 25 2012-08-10 22:00:00
24 22 2012-08-10 19:00:00 <=== I would like to return this row
24 22 2012-08-10 17:00:00
21 17 2012-08-10 15:00:00

所以,我想做的是能够:

 1) Select the "newest" row, based on timestamp AND 
 2) Select the 'user_2' column when given a value.  

我尝试过类似的方法:

 SELECT *
 FROM my_table
 WHERE user_2 = 22
 AND timestamp = (
 SELECT MAX( timestamp )
 FROM my_table )
 LIMIT 1 

但这不会返回我正在寻找的行。修复此查询的任何帮助都会很棒。

非常感谢。

【问题讨论】:

    标签: mysql select timestamp


    【解决方案1】:

    另一种方法是在计算MAX(timestamp) 时将GROUP BY user_2 列。这样做会使MAX(timestamp) 计算的不是整个表中的最新日期,而是每组具有相同user_2 值的记录的最新时间戳。

    因此,例如,您的查询可能是:

    SELECT * FROM my_table
    WHERE user_2 = 22
    AND timestamp =
      (SELECT MAX(timestamp) FROM my_table
       WHERE user_2 = 22
       GROUP BY user_2)
    LIMIT 1;
    

    此查询改编自我在this excellent answer 中找到的答案。

    【讨论】:

    • 这对接受的答案有什么好处?
    【解决方案2】:

    如果有人在 SQL Server 中遇到类似问题,这对你有用(上一篇文章中建议的 MySQL 查询在 SQL Server 中不起作用):

    SELECT * FROM my_table 
    WHERE    timestamp =  ( SELECT MAX( timestamp ) FROM my_table 
                            WHERE user_2 = 22 )
    

    【讨论】:

    • 我得到了同样的解决方案,但是,有一个大表,即使在时间戳上有索引,查询也非常非常慢。有什么更聪明的方法吗?
    【解决方案3】:

    这就是我的全部。

    SELECT timestamp 
           FROM my_table 
           WHERE user_22 = '22' 
           ORDER BY timestamp DESC /*or ASC*/
    

    当你查询它时,代码是

    while($row = mysql_fetch_array(the sql query)){
    $timestamp = $row['timestamp']
    }
    

    【讨论】:

      【解决方案4】:
      SELECT * FROM my_table -- standard stuff
         WHERE user_2 = 22 -- predicate
         ORDER BY timestamp DESC -- this means highest number (most recent) first
         LIMIT 1; -- just want the first row
      

      编辑:

      顺便说一句,如果您想知道为什么您的原始查询不起作用,让我们分解一下:

      • my_table中选择一些东西...
      • 其中user_2 = 22
      • timestamp = (一些价值,我们暂时搁置)
      • 限制 1

      现在,回到 timestamp 值,它来自您的子查询:

      SELECT MAX( timestamp ) FROM my_table
      

      请注意,此子查询不会限制基于user_2 的任何行——它会询问整个表中的最大时间戳。最大时间戳是上表中的第一个:(user_1 = 23, user_2 = 25, timestamp = 2012-08-10 22:00:00)。

      所以,让我们把它插回顶级查询:

      • my_table中选择一些东西...
      • 其中 user_2 = 22
      • 和时间戳 = 2012-08-10 22:00:00
      • 限制 1

      ...你可以看到没有这样的一行。

      【讨论】:

      • 非常感谢。我对自己太苛刻了。这就是我在过去 36 小时内保持清醒的结果。 :-)
      • @Dodinas 不客气!我发现来自非 SQL 编程,我们一遍又一遍地被教导将问题分解为更小的问题,在 SQL 查询中也有这样做的趋势。不幸的是,这通常会使它们变得复杂——而且效率也更低。这是一种心理转换,需要一些时间才能掌握。顺便说一句,我编辑了我的问题,以解释一下您的原始查询在哪里遇到了麻烦。
      • 太棒了!这很有帮助。再次感谢。
      • 哈哈哈,真是天才。 +1 为简单起见。
      • 我想知道当有很多(比如 100K+)行时该查询的性能。引擎需要在返回该列表的第一项之前对所有内容进行排序。如果我在时间戳列上创建索引,引擎是否足够智能以导航 btree 以找到我正在寻找的一个元素,而不是进行整个排序?
      猜你喜欢
      • 1970-01-01
      • 2014-01-16
      • 2013-01-10
      • 1970-01-01
      • 1970-01-01
      • 2014-03-10
      • 1970-01-01
      • 2023-02-01
      • 1970-01-01
      相关资源
      最近更新 更多