从 2 个更优化的表中获取 MySQL 的最新记录
Get the newest record from MySQL from 2 tables more optimalized
我在 SQL 中遇到一些查询问题。
我有 2 tables.
people
+----+--------+------+
| id | name | val2 |
+----+--------+------+
| 1 | john | 12 |
| 2 | adam | 5 |
| 3 | alfred | 3 |
+----+--------+------+
data
+----+----+----+-----+---------------------+
| id | v1 | v2 | v3 | date |
+----+----+----+-----+---------------------+
| 1 | 4 | 15 | 18 | 2020-10-16 11:15:53 |
| 1 | 2 | 12 | 17 | 2020-10-16 11:22:53 |
| 1 | 3 | 13 | 16 | 2020-10-16 11:32:53 |
| 2 | 1 | 16 | 15 | 2020-10-16 13:22:53 |
| 2 | 3 | 13 | 25 | 2020-10-16 13:42:53 |
| 2 | 4 | 12 | 35 | 2020-10-16 14:12:53 |
| 3 | 1 | 21 | 12 | 2020-10-16 14:12:53 |
| 3 | 2 | 28 | 42 | 2020-10-16 15:12:53 |
| 3 | 4 | 30 | 72 | 2020-10-16 16:12:53 |
+----+----+----+-----+---------------------+
我需要输入一个 table ID, NAME, v1,v2,v3,date 作为第一个 table 所有对象的新日期
像这样:
RESULT
+----+--------+----+----+-----+---------------------+
| id | name | v1 | v2 | v3 | date |
+----+--------+----+----+-----+---------------------+
| 1 | john | 3 | 13 | 16 | 2020-10-16 11:32:53 |
| 2 | adam | 4 | 12 | 35 | 2020-10-16 14:12:53 |
| 3 | alfred | 4 | 30 | 72 | 2020-10-16 16:12:53 |
+----+--------+----+----+-----+---------------------+
我需要来自第一个 table 的所有人的第二个 TABLE 的最新记录。
我尝试通过这个查询来做到这一点:
SELECT people.id,
people.name,
data.v1,
data.v2,
data.v3,
max(data.date)
FROM people
JOIN DATA ON people.id = data.id
GROUP BY people.id
我得到了最新的数据,但是 v1、v2、v3 是随机的 table。
一个简单的方法使用 window 函数:
SELECT p.id, p.name, d.v1, d.v2, d.v3, d.date)
FROM people p JOIN
(SELECT d.*,
ROW_NUMBER() OVER (PARTITION BY d.id ORDER BY d.date DESC) as seqnum
FROM data d
) d
ON p.id = d.id AND d.seqnum = 1;
注意:data
中的连接列是 id
似乎很奇怪。我希望它被称为 people_id
.
您需要 data
中的整行,因此聚合不是此处的选项。在大多数数据库中,你的查询会失败,因为 select
和 group by
子句不一致......但是 MySQL,不知何故,不幸的是,给了你足够的绳子让开发人员上吊.您的查询运行(如果 sql 模式 ONLY_FULL_GROUP_BY
被禁用),但实际上等同于:
SELECT people.id, people.name, ANY_VALUE(data.v1), ANY_VALUE(data.v2), ANY_VALUE(data.v3), MAX(data.date)
FROM people
JOIN data on people.id = data.id
GROUP BY people.id
现在可以清楚地看到数据库为您提供 data
行中与连接条件匹配的任何值 - 这可能属于也可能不属于具有最新日期的行。
您实际上需要过滤而不是分组。一个选项使用子查询:
select p.id, p.name, d.v1, d.v2, d.v3, d.date
from people p
inner join data d on d.id = p.id
where d.date = (select max(d1.date) from data d1 where d1.id = d.id)
这种方法的好处是它适用于 MySQL 的所有版本,包括 8.0 之前的版本,其中 window 功能不可用。
我在 SQL 中遇到一些查询问题。 我有 2 tables.
people
+----+--------+------+
| id | name | val2 |
+----+--------+------+
| 1 | john | 12 |
| 2 | adam | 5 |
| 3 | alfred | 3 |
+----+--------+------+
data
+----+----+----+-----+---------------------+
| id | v1 | v2 | v3 | date |
+----+----+----+-----+---------------------+
| 1 | 4 | 15 | 18 | 2020-10-16 11:15:53 |
| 1 | 2 | 12 | 17 | 2020-10-16 11:22:53 |
| 1 | 3 | 13 | 16 | 2020-10-16 11:32:53 |
| 2 | 1 | 16 | 15 | 2020-10-16 13:22:53 |
| 2 | 3 | 13 | 25 | 2020-10-16 13:42:53 |
| 2 | 4 | 12 | 35 | 2020-10-16 14:12:53 |
| 3 | 1 | 21 | 12 | 2020-10-16 14:12:53 |
| 3 | 2 | 28 | 42 | 2020-10-16 15:12:53 |
| 3 | 4 | 30 | 72 | 2020-10-16 16:12:53 |
+----+----+----+-----+---------------------+
我需要输入一个 table ID, NAME, v1,v2,v3,date 作为第一个 table 所有对象的新日期 像这样:
RESULT
+----+--------+----+----+-----+---------------------+
| id | name | v1 | v2 | v3 | date |
+----+--------+----+----+-----+---------------------+
| 1 | john | 3 | 13 | 16 | 2020-10-16 11:32:53 |
| 2 | adam | 4 | 12 | 35 | 2020-10-16 14:12:53 |
| 3 | alfred | 4 | 30 | 72 | 2020-10-16 16:12:53 |
+----+--------+----+----+-----+---------------------+
我需要来自第一个 table 的所有人的第二个 TABLE 的最新记录。 我尝试通过这个查询来做到这一点:
SELECT people.id,
people.name,
data.v1,
data.v2,
data.v3,
max(data.date)
FROM people
JOIN DATA ON people.id = data.id
GROUP BY people.id
我得到了最新的数据,但是 v1、v2、v3 是随机的 table。
一个简单的方法使用 window 函数:
SELECT p.id, p.name, d.v1, d.v2, d.v3, d.date)
FROM people p JOIN
(SELECT d.*,
ROW_NUMBER() OVER (PARTITION BY d.id ORDER BY d.date DESC) as seqnum
FROM data d
) d
ON p.id = d.id AND d.seqnum = 1;
注意:data
中的连接列是 id
似乎很奇怪。我希望它被称为 people_id
.
您需要 data
中的整行,因此聚合不是此处的选项。在大多数数据库中,你的查询会失败,因为 select
和 group by
子句不一致......但是 MySQL,不知何故,不幸的是,给了你足够的绳子让开发人员上吊.您的查询运行(如果 sql 模式 ONLY_FULL_GROUP_BY
被禁用),但实际上等同于:
SELECT people.id, people.name, ANY_VALUE(data.v1), ANY_VALUE(data.v2), ANY_VALUE(data.v3), MAX(data.date)
FROM people
JOIN data on people.id = data.id
GROUP BY people.id
现在可以清楚地看到数据库为您提供 data
行中与连接条件匹配的任何值 - 这可能属于也可能不属于具有最新日期的行。
您实际上需要过滤而不是分组。一个选项使用子查询:
select p.id, p.name, d.v1, d.v2, d.v3, d.date
from people p
inner join data d on d.id = p.id
where d.date = (select max(d1.date) from data d1 where d1.id = d.id)
这种方法的好处是它适用于 MySQL 的所有版本,包括 8.0 之前的版本,其中 window 功能不可用。