[英]Mysql Join get Latest value of each group
Mysql 版本:8.0.21
我正在寻找每个具有“水果”类型的“TableData”的最新值。
Table Name: TableNames
_________________________________________
| id | name | id_group | type |
|-----------------------------------------|
| 0 | AppleGroup | apple | fruit |
| 1 | BananaGroup | banana | fruit |
| 2 | OtherGroup | other | other |
Table Name: TableData
__________________________
| id | id_group | value |
|--------------------------|
| 0 | apple | 12 |
| 1 | banana | 8 |
| 2 | apple | 3 | <--get latest
| 3 | banana | 14 |
| 4 | banana | 4 | <--get latest
通过此查询,我得到了所有项目,但我正在寻找每个项目中的最新项目。 我已经尝试过分组依据和排序依据,但问题是我首先需要排序依据然后分组依据,这在 Mysql 中似乎是不可能的。
SELECT
n.name,
d.value
FROM TableNames n
INNER JOIN
(
SELECT *
FROM TableData
) d ON d.`id_group` = n.`id_group`
WHERE type = 'fruit'
Expected ouput:
_____________________
| name | value |
|---------------------|
| AppleGroup | 3 |
| BananaGroup | 4 |
如果没有ROW_NUMBER()
,因为您可以使用旧版本 MySQL(8.0 之前),您可以使用 max(id) 创建内部连接:
SELECT
TableNames.name,
TableData.value
FROM
TableData
INNER JOIN (
SELECT
id_group,
MAX(id) as max
FROM TableData
GROUP BY id_group) x ON x.id_group = TableData.id_group
INNER JOIN TableNames on TableNames.id_group = TableData.id_group
WHERE x.max = TableData.id
参见: DBFIDDLE
在 MySQL 8+ 上,我们可以使用ROW_NUMBER()
:
WITH cte AS (
SELECT tn.name, tn.id_group, td.value,
ROW_NUMBER() OVER (PARTITION BY td.id_group ORDER BY td.id DESC) rn
FROM TableNames tn
INNER JOIN TableData td
ON td.id_group = tn.id_group
WHERE tn.type = 'fruit'
)
SELECT name, value
FROM cte
WHERE rn = 1
ORDER BY id_group;
为了优化,可以考虑在TableData
表中增加如下索引:
CREATE INDEX idx ON TableData (id_group);
请注意,在 InnoDB 上,MySQL 将自动在索引末尾包含id
,因此索引为(id_group, id)
。 这应该让 MySQL 有效地在 CTE 中进行连接并计算ROW_NUMBER
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.