簡體   English   中英

MySQL:當最大值不唯一時,獲取每組中的最大行

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM