在 mysql 中,在 GROUP BY name 之前按日期和时间排序

我有一张这样的桌子:

name    date         time
tom | 2011-07-04 | 01:09:52
tom | 2011-07-04 | 01:09:52
mad | 2011-07-04 | 02:10:53
mad | 2009-06-03 | 00:01:01

我想要最古老的名字:

SELECT *
ORDER BY date ASC, time ASC
GROUP BY name

(- > 不起作用!)

现在它应该给我第一个疯狂(有更早的日期)然后汤姆

但与 GROUP BY name ORDER BY date ASC, time ASC给我较新的疯了第一,因为它组之前,它排序!

再说一遍: 问题是我不能在分组之前按日期和时间排序,因为 GROUP BY 必须在 ORDER BY 之前!

142509 次浏览

使用子选项:

select name, date, time
from mytable main
where date + time = (select min(date + time) from mytable where name = main.mytable)
order by date + time;

我想这就是你想要的:

SELECT name, min(date)
FROM myTable
GROUP BY name
ORDER BY min(date)

目前,您必须通过 STR _ TO _ DATE 创建 mysql 日期:

STR_TO_DATE(date + ' ' + time, '%Y-%m-%d %h:%i:%s')

所以:

SELECT name, min(STR_TO_DATE(date + ' ' + time, '%Y-%m-%d %h:%i:%s'))
FROM myTable
GROUP BY name
ORDER BY min(STR_TO_DATE(date + ' ' + time, '%Y-%m-%d %h:%i:%s'))

另一种方法:

SELECT *
FROM (
SELECT * FROM table_name
ORDER BY date ASC, time ASC
) AS sub
GROUP BY name

在它命中的第一个匹配结果上分组。如果第一个匹配的命中碰巧是你想要的,那么一切都应该按照预期的那样工作。

我更喜欢这种方法,因为子查询符合逻辑,而不是使用其他条件。

由于我不能评论 user1908688的回答,这里给 MariaDB 用户一个提示:

SELECT *
FROM (
SELECT *
ORDER BY date ASC, time ASC
LIMIT 18446744073709551615
) AS sub
GROUP BY sub.name

Https://mariadb.com/kb/en/mariadb/why-is-order-by-in-a-from-subquery-ignored/

这对我很有效:

SELECT *
FROM your_table
WHERE id IN (
SELECT MAX(id)
FROM your_table
GROUP BY name
);

在这个问题上,我有一个不同的变化,我只有一个 DATETIME字段,在 group bydistinct之后需要一个 limit,排序降序基于 datetime字段,但这是什么帮助我:

select distinct (column) from
(select column from database.table
order by date_column DESC) as hist limit 10

在这个使用拆分字段的例子中,如果您可以对 concat 进行排序,那么您可能会得到以下内容:

select name,date,time from
(select name from table order by concat(date,' ',time) ASC)
as sorted

然后,如果你想限制,你只需在结尾处加上你的限制语句:

select name,date,time from
(select name from table order by concat(date,' ',time) ASC)
as sorted limit 10

这不是确切的答案,但是这可能有助于人们在 mysql 中寻找解决某些问题的方法,即在分组之前排序 row。

我来到这个线程,当我想找到最新的一行(它是 order by date desc,但是只能得到一个特定列类型的结果,它是 group by column name)。

另一种解决这类问题的方法是使 聚合的使用。

因此,我们可以让查询像往常一样运行,其中 分类的 ASC和引入新的字段作为 max(doc) as latest_doc,这将给出最新的日期,由同一列分组。

假设您现在希望查找特定列的数据,而 最大聚合无法完成。 通常,为了查找特定列的数据,可以使用 GROUP_CONCAT aggregator,使用一些不能出现在该列中的唯一分隔符,比如 GROUP_CONCAT(string SEPARATOR ' ') as new_column,在访问它时,可以拆分/扩展 new _ column 字段。

再说一次,这听起来可能不是每个人都这么认为。我这样做了,也很喜欢它,因为我只写了几个函数,而且不能运行子查询。我正在为 PHP 开发编码符框架。

不确定的复杂性,以及,可能有人可以提供一些光。

问候:)

解决这个问题的另一种方法是使用 LEFT JOIN,它可能更有效率。我将首先从一个只考虑日期字段的示例开始,因为将 date + time 存储在一个 datetime 列中可能更为常见,而且我还希望查询保持简单,以便更容易理解。

因此,对于这个特定的示例,如果您想基于 约会列显示 最老的记录,并假设您的表名称为 people,那么您可以使用以下查询:

SELECT p.* FROM people p
LEFT JOIN people p2 ON p.name = p2.name AND p.date > p2.date
WHERE p2.date is NULL
GROUP BY p.name

LEFT JOIN所做的是,当 p.date列处于最小值时,左连接上没有值较小的 p2.date,因此相应的 p2.date将是 NULL。因此,通过添加 WHERE p2.date is NULL,我们确保只显示具有最早日期的记录。

类似地,如果想要显示 最新的记录,只需更改 LEFT JOIN中的比较运算符:

SELECT p.* FROM people p
LEFT JOIN people p2 ON p.name = p2.name AND p.date < p2.date
WHERE p2.date is NULL
GROUP BY p.name

现在,对于这个日期 + 时间为单独列的特殊示例,如果您希望基于两列合并的日期时间进行查询,则需要以某种方式添加它们,例如:

SELECT p.* FROM people p
LEFT JOIN people p2 ON p.name = p2.name AND p.date + INTERVAL TIME_TO_SEC(p.time) SECOND > p2.date + INTERVAL TIME_TO_SEC(p2.time) SECOND
WHERE p2.date is NULL
GROUP BY p.name

您可以在 保持某列的分组最大值的行页面上阅读更多关于这方面的内容(还可以看到完成这项工作的其他方法)。

在甲骨文,这对我有用

SELECT name, min(date), min(time)
FROM table_name
GROUP BY name

为我工作 mysql SELECT * FROM (SELECT number,max (date _ add) as datea FROM sms _ chat group by number) as sup order by datea desc

如果不按照最大日期和名称分组排序,可以执行以下查询:

SELECT name,MAX(date) FROM table  group by name ORDER BY name

其中日期可以由一些日期或日期时间字符串。它响应你的每一个名字的日期的最大值