【问题标题】:SQL - GROUP BY max valueSQL - 按最大值分组
【发布时间】:2016-03-29 20:23:12
【问题描述】:

注意:我不确定我是否给这个问题提供了最重要的标题,因为我不确定解决这个问题的正确方法,但我无法在任何地方找到其他示例,因为它是一个非常具体的查询.

所以,我有一个表“votes”,其中填充了用户创建的投票(在 user_id 列中唯一标识为数字),这些投票对应于另一个表中的相关帖子(投票记录“upvote”用户界面中的每个相关帖子)。

我打算按照为每个帖子创建的最新投票的顺序(按日期时间)对这些投票进行排序post_id 列),因此,避免重复的返回值每个 post_id

我输入以下查询:

SELECT id, user_id, post_id, created, MAX(created)
FROM votes
GROUP BY post_id, user_id
ORDER BY max(created) DESC

然后被退回:

Table: votes

 id  |  user_id  |  post_id  |        created        |    MAX(created)
 ----+-----------+-----------+-----------------------+--------------------
 115 | 1         | 42        | 2014-07-03 23:08:31   | 2016-03-07 12:08:31
 ----+-----------+-----------+-----------------------+--------------------        
 237 | 2         | 101       | 2014-02-13 23:05:14   | 2016-03-05 23:05:14         
 ----+-----------+-----------+-----------------------+--------------------  
 431 | 7         | 944       | 2014-10-22 22:58:37   | 2016-03-03 19:58:37
 ----+-----------+-----------+-----------------------+--------------------
 255 | 15        | 101       | 2014-02-15 14:02:01   | 2016-02-01 23:05:14
 ----+-----------+-----------+-----------------------+--------------------
 ... | ...       | ...       | ...                   | ...

如您所见,post_id“101”有一个重复项。此查询的结果似乎按每个 user_id 的最大创建时间排序,显示重复的 post_id,例如“101”有两个 post_id 列行,当我只想显示具有最大创建时间的“101”的唯一 post_id 列值(MAX( 创建))。

post_iduser_id 列似乎必须组合在一起,否则如果我只是按 post_id 分组,我无法按 MAX 排序(created),因为它不会返回每个 post_id 的 max(created)。

如何删除这些不返回最大创建时间的重复 post_id 值?

我追求的是什么:

Table: votes

 id  |  user_id  |  post_id  |        created        |    MAX(created)
 ----+-----------+-----------+-----------------------+--------------------
 115 | 1         | 42        | 2014-07-03 23:08:31   | 2016-03-07 12:08:31
 ----+-----------+-----------+-----------------------+--------------------        
 237 | 2         | 101       | 2014-02-13 23:05:14   | 2016-03-05 23:05:14         
 ----+-----------+-----------+-----------------------+--------------------  
 431 | 7         | 944       | 2014-10-22 22:58:37   | 2016-03-03 19:58:37
 ----+-----------+-----------+-----------------------+--------------------
 ... | ...       | ...       | ...                   | ...

【问题讨论】:

  • 那么不要按 user_ID 分组。如果您只关注 max(create) 并且不关心该 max(created) 数据返回的 user_ID 是什么,只要它与相同的 Post_ID 相关联,则不要按 user_ID 分组。
  • 如果我只是按 post_id 分组,我无法按 MAX(created) 排序,因为它不会返回每个 post_id 的 max(created),与最后一个 post_id 的 user_id 相关跨度>

标签: mysql database group-by duplicates sql-order-by


【解决方案1】:

假设您只想要每个帖子的最后一票:

SELECT  v.*
FROM    posts p
JOIN    votes v
ON      v.id =
        (
        SELECT  id
        FROM    votes vi
        WHERE   post_id = p.id
        ORDER BY
                created DESC
        LIMIT 1
        )

【讨论】:

  • 另外,这并没有返回每个投票的 MAX(created) 并且忽略了一个事实,即 v.post_id = p.id 会有多种情况
  • 确实如此。聪明的家伙。谢谢!
  • 这个查询运行很慢,但是
  • @user1228907:在 votes.created 上创建索引并按条件添加订单。但是,如果您希望它真正快速,您应该实现此查询:创建一个表 last_vote (post_id primary key, vote_id, created) 并在每次添加投票时在触发器中更新它
【解决方案2】:

如果您正在寻找最后一位编辑post_iduser_id,请尝试group by post_id 并按时间降序排序(或id,如果它是自动递增的)。

 SELECT tbl.* , GROUP_CONCAT('(',tbl.user_id,',',tbl.created,')') as myhistory FROM
   (SELECT id, user_id, post_id, created, MAX(created)
   FROM votes
   ORDER BY max(created) DESC
   ) as tbl
 GROUP BY tbl.post_id

如果您需要 (user_id,time) 的历史记录,您可以使用 group_concat 函数,如 myhistory 列的代码中所述。

【讨论】:

    【解决方案3】:
    SELECT maintable.*
    FROM TABLE_NAME maintable
    LEFT OUTER JOIN TABLE_NAME temporarytable
     ON maintable.GROUPING_BY_COLUMN = temporarytable.GROUPING_BY_COLUMN
     AND maintable.COLUMN_WHERE_THE_MAXIMUM_IS_NEEDED < temporarytable.COLUMN_WHERE_THE_MAXIMUM_IS_NEEDED
    WHERE temporarytable.COLUMN_WHERE_THE_MAXIMUM_IS_NEEDED IS NULL
    ORDER BY PRIMARY_KEY_COLUMN DESC
    LIMIT 50;
    

    从组中获取最大值的另一种方法。此查询不需要聚合,就像“GROUP BY”一样。

    另外,在使用“GROUP BY”进行分组时,每个分组都是按主键排序的,这也很耗时。

    我的查询将一张表的值与另一张表的值进行比较。直到他再也找不到更多了。如果没有找到其他内容,则这是最大值。

    此查询可以帮助您节省从组中获取最大值的时间。

    【讨论】:

      猜你喜欢
      • 2021-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多