MySQL:获取时间戳最多的行,并带有多个值的分组依据

时间:2019-04-05 14:16:48

标签: mysql

给出以下模式:

+---------------------+--------------+------+-----+---------+----------------+
| Field               | Type         | Null | Key | Default | Extra          |
+---------------------+--------------+------+-----+---------+----------------+
| id                  | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| timestamp           | int(11)      | NO   | MUL | 0       |                |
| col1                | varchar(255) | YES  | MUL |         |                |
| col2                | varchar(255) | YES  |     |         |                |
.....

+---------------------+--------------+------+-----+---------+----------------+

我可以执行以下查询:

SELECT * from report_data GROUP BY concat(host_name, ";", service_description)

对于每种唯一的col1和col2组合,我都会得到一行。似乎总是返回具有组合的第一行(即最低ID)。

但是,在我的数据集中,我有多行具有唯一的col1和col2组合,并且我希望它们具有最高的时间戳。时间戳可能是乱序的,即ID最高的记录不一定具有最高的时间戳。

我将如何实现?

样本数据:

+-----+------------+-----------+------------------------+
| id  | timestamp  | col1      | col2                   |
+-----+------------+-----------+------------------------+
| 916 | 1          | val1      | valA                   |
| 915 | 2          | val2      | valB                   |
| 914 | 5          | val1      | valB                   |
| 913 | 4          | val1      | valA                   |
+-----+------------+-----------+------------------------+

在上面的示例中,我想让这些行退回(有两次出现,其中col1和col2相同,将返回时间戳最大的一次)

+-----+------------+-----------+------------------------+
| id  | timestamp  | col1      | col2                   |
+-----+------------+-----------+------------------------+
| 915 | 2          | val2      | valB                   |
| 914 | 5          | val1      | valB                   |
| 913 | 4          | val1      | valA                   |
+-----+------------+-----------+------------------------+

1 个答案:

答案 0 :(得分:2)

mySQL的大多数版本都支持:较新的版本,我们可以使用窗口/分析功能来执行此操作...

SELECT A.ID, A.timestamp, A.col1, A.col2
FROM report_data A
INNER JOIN (SELECT max(timestamp) TS, col1, col2
            FROM report_Data
            GROUP BY COl1, Col2) B
 on A.timestamp = B.TS
and A.Col1 = B.col1
and A.Col2 = B.Col2

使用8.0 +的mySQL

WITH CTE AS (SELECT A.*, Row_number() over (partition by Col1, col2 order by Timestamp Desc) RN
             FROM report_data)
SELECT * 
FROM CTE
INNER JOIN report_data B
 on CTE.ID B.ID
WHERE CTE.RN = 1