MySQL通过两列从分组中选择最后一行

MySQL通过两列从分组中选择最后一行,mysql,sql,Mysql,Sql,我试图从select中的每个组中获取最新的行,但有点扭曲 例如,获取下表: id , user_id , created_at , balance 1 , 1 , 2016-01-01 01:01:01 , 1 2 , 1 , 2016-01-01 01:01:01 , 2 您可以看到,在处创建的值对于同一用户是相同的,问题是我也不能依赖id字段,因为没有任何东西可以保证最大的id将是最后一个 如果创建的_at字

我试图从select中的每个组中获取最新的行,但有点扭曲

例如,获取下表:

 id , user_id , created_at          , balance 
 1  , 1       , 2016-01-01 01:01:01 , 1       
 2  , 1       , 2016-01-01 01:01:01 , 2       
您可以看到,在处创建的
值对于同一用户是相同的,问题是我也不能依赖id字段,因为没有任何东西可以保证最大的id将是最后一个

如果创建的_at字段不会重复,则以下查询将正常工作:

SELECT L.id
    , L.user_id
    , L.created_at
    , L.balance
FROM   log AS L
      JOIN
         (SELECT user_id
              , MAX(created_at) AS max_created_at
          FROM   log
          GROUP BY user_id) MAX_TIME ON L.user_id = MAX_TIME.user_id
                                  AND L.created_at = MAX_TIME.max_created_at;
但由于在处创建了重复的_,它将返回两行。 所以我不能只依赖于created_at字段,但我相信如果created_at是重复的,那么获得max id会得到我想要的结果

因此,我需要以某种方式将id行添加到这个“组”机制中。
你知道怎么做吗?

如果你真的不在乎选择哪一行,你可以根据唯一的行id排序,只选择前1行。如果您想要最后一行,即具有最大唯一id的行,您需要
orderby。。。描述

SELECT TOP 1
      L.id
    , L.user_id
    , L.created_at
    , L.balance
FROM   log AS L
      JOIN
         (SELECT user_id
              , MAX(created_at) AS max_created_at
          FROM   log
          GROUP BY user_id) MAX_TIME ON L.user_id = MAX_TIME.user_id
                                  AND L.created_at = MAX_TIME.max_created_at;
                                  ORDER BY L.id DESC

如果您选择哪一行并不重要,您可以根据唯一的行id进行排序,只选择前1行。如果您想要最后一行,即具有最大唯一id的行,您需要
orderby。。。描述

SELECT TOP 1
      L.id
    , L.user_id
    , L.created_at
    , L.balance
FROM   log AS L
      JOIN
         (SELECT user_id
              , MAX(created_at) AS max_created_at
          FROM   log
          GROUP BY user_id) MAX_TIME ON L.user_id = MAX_TIME.user_id
                                  AND L.created_at = MAX_TIME.max_created_at;
                                  ORDER BY L.id DESC

如果您创建的表的ID为auto_increment(我强烈建议使用这种方式),那么最大的一行应该是最新的一行

因此:

(只需将在
处创建的
替换为
id


但是,如果您没有“正常”ID,我认为没有办法做到这一点…

如果您使用ID作为自动增量创建表(我强烈建议使用这种方式),最大的一行应该是最新的一行

因此:

(只需将在
处创建的
替换为
id


但是,如果您没有“正常”ID,我认为没有办法做到这一点…

为什么您实际上需要该自连接

不会

SELECT L.id
, L.user_id
, L.created_at
, L.balance
FROM log AS L
GROUP BY L.user_id
ORDER BY L.created_at DESC, L.id DESC;
你得到了预期的排吗


说明:首先进行排序,这样最新的日期时间已经在第一行中。由于可能存在重复的日期时间值,我们添加了另一个按id排序。现在,具有最新日期时间和最高id的行将位于第一行,然后按用户id对结果进行分组。

为什么实际需要该self join

不会

SELECT L.id
, L.user_id
, L.created_at
, L.balance
FROM log AS L
GROUP BY L.user_id
ORDER BY L.created_at DESC, L.id DESC;
你得到了预期的排吗



说明:首先进行排序,这样最新的日期时间已经在第一行中。由于可能存在重复的日期时间值,我们添加了另一个按id排序。现在,具有最新日期时间和最高id的行将位于第一行,然后按用户id对结果进行分组。

他说:>问题是我无法也不要依赖id字段,因为没有任何东西可以保证最大的id将是最后一个。我仍然在通过创建来最大化。我只是通过使用ORDER by不显著地选择单个id来缩小重复结果。此查询的问题是它将准确返回一行。需要的是返回最新的一行id每一个用户。@emul您的问题是,您没有定义在
处创建的
字段之外的“最近”是什么意思。对于上面的数据,两个字段都是“最近”的,所以都返回它们(或只返回一个)是正确的。如果你没有其他方法来确定最近的行与你所拥有的数据,那么识别最重读者是不可能的。@ LCIII,正如我所写的,如果在CREATEDATION字段中有重复,我会认为更大的ID的行是最新的一个。我不是说它是一个完美的溶胶。但是我想这是一个很接近的结果,他说:>问题是我也不能依赖id字段,因为没有任何东西可以保证最大的id将是最后一个…我仍然在通过创建最大值。我只是通过使用ORDER by不显著地选择单个id来缩小重复结果。这个查询的问题是它将精确返回一行。需要的是返回每个用户的最新一行。@emul您的问题是,您尚未定义在
处创建的字段之外的“最新”含义。对于上面的数据,这两个字段都是“最新”的,因此将它们都返回(或仅返回一个)是正确的。如果你没有其他方法来确定最近的行与你所拥有的数据,那么识别最重读者是不可能的。@ LCIII,正如我所写的,如果在CREATEDATION字段中有重复,我会认为更大的ID的行是最新的一个。我不是说它是一个完美的溶胶。注意:但我想这是一个很接近的问题,因为所有非用户id字段也需要聚合,所以这不会引发错误吗?不,为什么要聚合?只有使用组函数才能聚合非分组字段,例如SUM(),AVG(),…我不确定您希望此查询返回什么。如果您使用group by,您必须在group by语句中列出字段,或者以某种方式进行聚合。这不会引发错误,因为所有非用户id字段也需要聚合吗?不,为什么要聚合?非分组字段的聚合仅在group中发生函数,例如SUM()、AVG(),…我不确定您希望此查询返回什么。如果您使用group by,您必须列出group by语句中的字段,或者以某种方式进行聚合。问题是,正如我所写的,我不能依赖自动递增字段。原因是这是一个日志表,条目不一定按顺序排列。@emul OK,但我在这种情况下,您不能“真的”选择最新的(是的,它是基于日期工作的,但当日期相同时?)…为此,您需要一个绝对标识符,您可以依赖于注册顺序…因此我没有其他建议,只需创建第二个
id
字段,由
填充