[英]MySQL: get max row in each group when max value is not unique
有很多與此相關的問題,但我找不到一個有一個可靠的例子來說明如何做我想做的事。 當最大值在組中不是唯一的時,我需要為每個組獲取一個最大行。 這是一張表:
| id | source | name | message_time |
|----|--------|------|--------------|
| 1 | a | cool | 2020-08-18 |
| 2 | a | cool | 2020-08-18 |
| 3 | a | neat | 2020-08-02 |
| 4 | b | nice | 2020-08-19 |
| 5 | b | wow | 2020-08-17 |
對於每個source
,我需要一個與最大message_time
關聯的完整行。 由於最大消息時間在組內不是唯一的,因此這兩個都是有效的輸出:
| id | source | name | message_time |
|----|--------|------|--------------|
| 1 | a | cool | 2020-08-18 |
| 4 | b | nice | 2020-08-19 |
| id | source | name | message_time |
|----|--------|------|--------------|
| 2 | a | cool | 2020-08-18 |
| 4 | b | nice | 2020-08-19 |
當有多個最大候選人時,我只想隨機 select 一行。 如何使用 mysql 查詢來實現這一點?
我正在使用 MySQL 5.7
編輯:
所以我又搞砸了一些,並意識到這是可行的:
SELECT table.*
FROM (
SELECT source FROM table
GROUP BY source
) groups
LEFT JOIN table
ON id = (
SELECT id FROM table
WHERE source = groups.source
ORDER BY message_time desc
LIMIT 1
);
我想我什至理解它為什么會起作用,但我不知道我在這里做什么不好,非常壞的做法。 另外,可以簡化嗎?
為此,您可以使用 row_number window function,這需要 mysql 8.0 或 Z4AAB337EFAB3B3BBFE77121 或更好。
select id, source, name, message_time
from (
select id, source, name, message_time,
row_number() over (partition by source order by message_time desc, rand()) as row_num
from a_table
) a_table_with_row_numbers
where row_num=1;
在早期版本中,您可以這樣做:
select
0+substr(max(concat(prefix,id)),19) id,
substr(max(concat(prefix,source)),19) source,
substr(max(concat(prefix,name)),19) name,
max(message_time)
from (
select id, source, name, message_time, concat(message_time, lpad(1e8*rand(),8,'0')) prefix
from a_table
) a_table_with_sortable_prefix_string
group by source;
SELECT
MAX(m.id) as id,
x.source,
x.message_time
FROM
(SELECT
source,
MAX(message_time) AS message_time
FROM
source
GROUP BY
source ) x
INNER JOIN source m ON m.source=x.source AND m.message_time=x.message_time
GROUP BY
x.source,
x.message_time;
這將 select 源和 max(message_time),
然后 select 該源和 message_time 的 max(id)
編輯:查詢中有一些錯字,並添加了一個測試:
使用創建的示例數據:
CREATE TABLE source (id INTEGER, source CHAR(1), name VARCHAR(10), message_time DATE);
INSERT INTO source VALUES
(1,'a','cool','2020-08-18'),
(2,'a','cool','2020-08-18'),
(3,'a','neat','2020-08-02'),
(4,'b','nice','2020-08-19'),
(5,'b','wow','2020-08-17');
output 查詢:
+------+--------+--------------+
| id | source | message_time |
+------+--------+--------------+
| 2 | a | 2020-08-18 |
| 4 | b | 2020-08-19 |
+------+--------+--------------+
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.