MySQL 组和 select 每个组的第一名
MySQL group and select only first from each group
我想执行一个查询,该查询将 select 仅显示给定组中的最新项目。
在这个例子中,我正在跟踪货车:
- 每次他们 return 到基地时,都会记录
check-in
信息 - 里程等...
- 每次他们送货时,都会记录
delivery
- 客户等...
这个 table 让我们知道给定 van
的历史记录。数据可以通过查询生成或随时存储 - 这不是问题。
id | checkin_id | delivery_id | van_id
----+------------+-------------+--------
24 | 15 | NULL | 3
25 | NULL | 28 | 3
26 | 16 | NULL | 4
27 | NULL | 29 | 3
28 | NULL | 30 | 4
29 | 17 | NULL | 5
我可以通过 ... WHERE van_id=3;
查询来查看面包车的历史记录 - 很好。
相反,我希望能够获得 vans
的列表以及他们最近的“事件”。结果是:
id | checkin_id | delivery_id | van_id
----+------------+-------------+--------
27 | NULL | 29 | 3
28 | NULL | 30 | 4
29 | 17 | NULL | 5
我跳转到了以下查询:
SELECT * FROM `history` GROUP BY `van_id`;
但这 return 出现以下错误:
#1055 - Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'database.history.checkin_id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
看完之后,我明白了这是怎么回事,不得不承认我的 SQL 有点过时了 - 我想要组中的哪些项目 returned?
将 checkin_id
和 delivery_id
添加到 GROUP BY
只是转移了问题 - 最终我得到了相同的数据集,只是排序不同。
激起了我的兴趣,图形确实有助于清楚地概述问题,谢谢@azerafati!
我想使用 FIRST()
或 LAST()
聚合函数 - but MySQL doesn't appear to have them.
如何在不处理应用程序中 所有 数据的情况下重现此行为?
我打算将其标记为重复,因为这个问题实际上被问得相当频繁,但我发现那些 question/answers 似乎很难搜索;所以这是通用模板:
SELECT t.*
FROM theTable AS t
INNER JOIN (
SELECT groupingValue, MIN(someValue) AS lowestValue
FROM theTable
GROUP BY groupingValue
) AS rIdent ON rIdent.groupingValue = t.groupingValue AND rIdent.lowestValue= t.someValue
lowest 在您的特定情况下是 min(id)...哦,哎呀;你的问题先说,但细节说最近(我会解释为最后),所以只需使用 MAX 而不是 MIN。 ..."groupingValue" 是 van_id。
编辑:如果在分组字段和用于标识 lowest/first/highest/recent 的字段上有索引,查询应该相当有效。
我猜你的 id
值是唯一的,后面的记录比前面的记录有更高的值。
您需要使用子查询获取每辆货车的最新 id
:
SELECT MAX(id) id, van_id
FROM history
GROUP BY van_id
然后将其加入您的详细查询。
SELECT h.*
FROM history h
JOIN (
SELECT MAX(id) id, van_id
FROM history
GROUP BY van_id
) m ON h.id = m.id AND h.van_id = m.van_id
但是因为您的 ID 值是唯一的,您可以进一步简化它。
SELECT h.*
FROM history h
JOIN (
SELECT MAX(id) id
FROM history
GROUP BY van_id
) m ON h.id = m.id
我想执行一个查询,该查询将 select 仅显示给定组中的最新项目。
在这个例子中,我正在跟踪货车:
- 每次他们 return 到基地时,都会记录
check-in
信息 - 里程等... - 每次他们送货时,都会记录
delivery
- 客户等...
这个 table 让我们知道给定 van
的历史记录。数据可以通过查询生成或随时存储 - 这不是问题。
id | checkin_id | delivery_id | van_id
----+------------+-------------+--------
24 | 15 | NULL | 3
25 | NULL | 28 | 3
26 | 16 | NULL | 4
27 | NULL | 29 | 3
28 | NULL | 30 | 4
29 | 17 | NULL | 5
我可以通过 ... WHERE van_id=3;
查询来查看面包车的历史记录 - 很好。
相反,我希望能够获得 vans
的列表以及他们最近的“事件”。结果是:
id | checkin_id | delivery_id | van_id
----+------------+-------------+--------
27 | NULL | 29 | 3
28 | NULL | 30 | 4
29 | 17 | NULL | 5
我跳转到了以下查询:
SELECT * FROM `history` GROUP BY `van_id`;
但这 return 出现以下错误:
#1055 - Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'database.history.checkin_id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
看完之后,我明白了这是怎么回事,不得不承认我的 SQL 有点过时了 - 我想要组中的哪些项目 returned?
将 checkin_id
和 delivery_id
添加到 GROUP BY
只是转移了问题 - 最终我得到了相同的数据集,只是排序不同。
我想使用 FIRST()
或 LAST()
聚合函数 - but MySQL doesn't appear to have them.
如何在不处理应用程序中 所有 数据的情况下重现此行为?
我打算将其标记为重复,因为这个问题实际上被问得相当频繁,但我发现那些 question/answers 似乎很难搜索;所以这是通用模板:
SELECT t.*
FROM theTable AS t
INNER JOIN (
SELECT groupingValue, MIN(someValue) AS lowestValue
FROM theTable
GROUP BY groupingValue
) AS rIdent ON rIdent.groupingValue = t.groupingValue AND rIdent.lowestValue= t.someValue
lowest 在您的特定情况下是 min(id)...哦,哎呀;你的问题先说,但细节说最近(我会解释为最后),所以只需使用 MAX 而不是 MIN。 ..."groupingValue" 是 van_id。
编辑:如果在分组字段和用于标识 lowest/first/highest/recent 的字段上有索引,查询应该相当有效。
我猜你的 id
值是唯一的,后面的记录比前面的记录有更高的值。
您需要使用子查询获取每辆货车的最新 id
:
SELECT MAX(id) id, van_id
FROM history
GROUP BY van_id
然后将其加入您的详细查询。
SELECT h.*
FROM history h
JOIN (
SELECT MAX(id) id, van_id
FROM history
GROUP BY van_id
) m ON h.id = m.id AND h.van_id = m.van_id
但是因为您的 ID 值是唯一的,您可以进一步简化它。
SELECT h.*
FROM history h
JOIN (
SELECT MAX(id) id
FROM history
GROUP BY van_id
) m ON h.id = m.id