Reputation: 3801
Given the following schema:
+---------------------+--------------+------+-----+---------+----------------+
| 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 | | | |
.....
+---------------------+--------------+------+-----+---------+----------------+
I can do the following query:
SELECT * from report_data GROUP BY concat(host_name, ";", service_description)
And I would get one row for each unique col1 and col2 combination. It seems it always returns the first row (i.e lowest id) that has the combination.
However in my dataset, I have multiple rows with unique col1 and col2 combinations, and I want the ones with the highest timestamp. The timestamps might be out of order, that is the record with the highest ID might not necessarily have the highest timestamp.
How would I achieve that?
Sample data:
+-----+------------+-----------+------------------------+
| id | timestamp | col1 | col2 |
+-----+------------+-----------+------------------------+
| 916 | 1 | val1 | valA |
| 915 | 2 | val2 | valB |
| 914 | 5 | val1 | valB |
| 913 | 4 | val1 | valA |
+-----+------------+-----------+------------------------+
In the above example I would like to have these rows back (there are two occurrences where col1 and col2 is the same, the one with the highest timestamp is returned)
+-----+------------+-----------+------------------------+
| id | timestamp | col1 | col2 |
+-----+------------+-----------+------------------------+
| 915 | 2 | val2 | valB |
| 914 | 5 | val1 | valB |
| 913 | 4 | val1 | valA |
+-----+------------+-----------+------------------------+
Upvotes: 0
Views: 35
Reputation: 35333
Supported in most version of mySQL: newer version we could use window/analytical functions to do this...
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
With 8.0 + of 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
Upvotes: 2