【问题标题】:mysql query issue: fetch latest postsmysql查询问题:获取最新帖子
【发布时间】:2014-02-08 00:02:58
【问题描述】:

我有一张用户帖子的表格。

我正在尝试使用此查询从帖子表中获取所有用户的最新帖子(只有 1 个):

SELECT * FROM Posts WHERE PostedAs = 'USER' GROUP BY PostedAsId ORDER BY
CONCAT(PostedDate,PostedTime) DESC

每个用户只给我 1 个帖子,但问题是,它给我的结果是基于所有帖子的降序排列。

我想获取所有用户的最新帖子。 我做错了什么?

【问题讨论】:

  • 为什么有两个单独的字段用于发布日期和时间?为什么不是单个日期时间字段?
  • 为什么不将发布的日期存储为 unix epoch,然后按那个顺序排序?
  • @helion3 除了非常特殊的情况外,不应在 MySQL 中使用 unix 时间戳。使用日期时间格式。
  • 为什么不呢?它的性能要好得多,占用的空间更少,并且与时区无关。
  • @helion3 好的,假设您想要查询特定日期的所有记录,并且您希望能够使用索引来执行此操作。你建议如何使用 unix 时间戳来做到这一点?

标签: php mysql sql database


【解决方案1】:

我认为这应该可行,但我不知道它是否足够快。

SELECT * 
FROM Posts p
WHERE PostedAs = 'USER' 
  AND CONCAT(PostedDate, PostedTime) = (SELECT MAX(CONCAT(PostedDate, PostedTime))
                                        FROM Posts p2
                                        WHERE p.PostedAsId = p2.PostedAsId)

【讨论】:

    【解决方案2】:
    $sql = mysql_query("SELECT * FROM Posts WHERE PostedAs = 'USER' GROUP BY PostedAsId ORDER BY
    CONCAT(PostedDate,PostedTime) DESC");
    while($row = mysql_fetch_array($sql)
    {
     echo $row['post'];
    }
    

    上面的结果是什么?

    【讨论】:

      【解决方案3】:

      假设您有一个日期时间字段,我们称之为PostedTimestamp,您可以这样进行查询:

      SELECT * FROM Posts
      INNER JOIN
          (SELECT
            PostedAsID,
            MAX(PostedTimestamp) AS latestPostTimestamp
          FROM Posts) AS LatestPosts
        ON Posts.PostedAsID = LatestPosts.PostedAsID
      WHERE Posts.PostedAs = 'USER'
      

      【讨论】:

        【解决方案4】:

        我已经复制了您在最初问题中描述的内容,但我看不出原始 concat 查询存在什么问题。

        表格如下:-

        mysql> desc posts;
        +------------+------------+------+-----+------------+----------------+
        | Field      | Type       | Null | Key | Default    | Extra          |
        +------------+------------+------+-----+------------+----------------+
        | PostId     | int(11)    | NO   | PRI | NULL       | auto_increment |
        | PostedAs   | varchar(8) | YES  |     | USER       |                |
        | PostedAsId | int(11)    | YES  |     | NULL       |                |
        | PostedDate | date       | YES  |     | 0000-00-00 |                |
        | PostedTime | time       | YES  |     | 00:00:00   |                |
        +------------+------------+------+-----+------------+----------------+
        5 rows in set (0.01 sec)
        

        表中的数据为:-

        mysql> select * from posts;
        +--------+----------+------------+------------+------------+
        | PostId | PostedAs | PostedAsId | PostedDate | PostedTime |
        +--------+----------+------------+------------+------------+
        |      1 | USER     |         22 | 1977-01-13 | 12:34:56   |
        |      2 | USER     |         47 | 1977-02-13 | 00:00:00   |
        |      3 | USER     |         52 | 1977-03-13 | 00:00:00   |
        |      4 | USER     |          7 | 1977-04-13 | 00:00:00   |
        |      5 | USER     |         47 | 1977-05-13 | 00:00:00   |
        |      6 | USER     |         22 | 1977-06-13 | 00:00:00   |
        |      7 | USER     |         52 | 1977-07-13 | 00:00:00   |
        |      8 | USER     |         52 | 1977-08-13 | 00:00:00   |
        |      9 | USER     |         59 | 1977-09-13 | 00:00:00   |
        |     10 | USER     |          7 | 1977-10-13 | 00:00:00   |
        |     11 | USER     |          7 | 1977-11-13 | 00:00:00   |
        +--------+----------+------------+------------+------------+
        11 rows in set (0.00 sec)
        

        运行问题中提供的查询

         mysql> SELECT * FROM Posts
                -> WHERE PostedAs = 'USER'
                -> GROUP BY PostedAsId
                -> ORDER BY CONCAT(PostedDate,PostedTime) DESC;
            +--------+----------+------------+------------+------------+
            | PostId | PostedAs | PostedAsId | PostedDate | PostedTime |
            +--------+----------+------------+------------+------------+
            |      9 | USER     |         59 | 1977-09-13 | 00:00:00   |
            |      4 | USER     |          7 | 1977-04-13 | 00:00:00   |
            |      3 | USER     |         52 | 1977-03-13 | 00:00:00   |
            |      2 | USER     |         47 | 1977-02-13 | 00:00:00   |
            |      1 | USER     |         22 | 1977-01-13 | 12:34:56   |
            +--------+----------+------------+------------+------------+
            5 rows in set (0.00 sec)
        

        同一查询的重新排列(排序):-

        mysql> SELECT * FROM Posts
            -> WHERE PostedAs = 'USER'
            -> GROUP BY PostedAsId
            -> ORDER BY PostedDate DESC, PostedTime DESC;
        +--------+----------+------------+------------+------------+
        | PostId | PostedAs | PostedAsId | PostedDate | PostedTime |
        +--------+----------+------------+------------+------------+
        |      9 | USER     |         59 | 1977-09-13 | 00:00:00   |
        |      4 | USER     |          7 | 1977-04-13 | 00:00:00   |
        |      3 | USER     |         52 | 1977-03-13 | 00:00:00   |
        |      2 | USER     |         47 | 1977-02-13 | 00:00:00   |
        |      1 | USER     |         22 | 1977-01-13 | 12:34:56   |
        +--------+----------+------------+------------+------------+
        5 rows in set (0.00 sec)
        

        使用您自己提供的 concat order by 或我自己的 double order by 似乎都可以为上面详述的表格/数据提供正确的结果,每个用户都被选中一次,发布日期/ID 是最新发布的.

        如果您的架构与我在此处提供的架构存在显着差异,请随时澄清。

        从表面上看,这个问题似乎在原来的问题中有解决方案。

        祝你好运!

        【讨论】:

        • 感谢您的介绍。这里的问题是。如您的示例所示,我们没有收到 PostedAsId 7 的最新帖子。此用户有 3 个帖子。对于用户 7,我们正在更新旧帖子。
        • @user3067928 你能发布至少部分表模式和数据集吗?它可能有助于追踪或澄清问题。再次。祝你好运。
        • 啊。没有意识到你找到了解决办法。请忽略... :)
        猜你喜欢
        • 2017-03-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-22
        • 2019-06-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多