MySQL - 如何在 JOIN 中使用相关子查询
Posted
技术标签:
【中文标题】MySQL - 如何在 JOIN 中使用相关子查询【英文标题】:MySQL - How to use a correlated subquery inside a JOIN 【发布时间】:2020-09-27 04:12:12 【问题描述】:我有两张桌子,Objects
和 Events
。
Objects
的结构如下:
ID | Password
-------------
0 | aaaa
1 | bbbb
事件的结构如下:
Object | Date | Type
--------------------------
0 | 2020-06-01 | 0
0 | 2020-06-02 | 1
我想要实现的是:对于每个 ID,获取最后一个关联的事件类型。在上面的示例中,对象0
将与1
相关联,因为1
是2020-06-02
上最后一个事件的类型。此外,当一个对象没有任何事件时,将1
关联到它。
我尝试为每个对象排序事件,这样我就可以使用查询加入我的对象信息:
SELECT ID, IFNULL(e.Type, 1)
FROM objects o
LEFT JOIN (
SELECT e.Object, e.Date, e.Type
FROM events e
WHERE e.Object = o.ID
ORDER BY e.Date DESC
LIMIT 1
) AS e ON e.Object = o.ID
由于o.ID
未知,它不起作用,但我真的想不出任何其他解决方案。因此我的问题是:如何在连接表的条件内使用外部表的属性?
如果有不清楚的地方请告诉我,谢谢。
【问题讨论】:
您对此样本数据的预期输出是什么? 我只需要 ID 和类型。这就是我使用SELECT ID, IFNULL(e.Type, 1)
的原因。
【参考方案1】:
SELECT ID, IFNULL(e.Type, 1)
FROM objects o
LEFT JOIN (
SELECT e.Object, max(e.Date), e.Type
FROM events e
GROUP BY e.Date DESC
) AS e ON e.Object = o.ID
【讨论】:
不,因为这只会返回加入其对象信息的最新事件,而我需要每个对象的最新事件。 啊,现在我明白了。然后您需要聚合子查询中的行。类似于修改后的答案【参考方案2】:你可以试试这样的:
SELECT o.id, max(e.date) AS date, e.type
FROM objects o
INNER JOIN events e ON(o.id = e.object)
GROUP BY o.id, e.type
ORDER BY e.date DESC;
输出
+------+------------+------+
| id | date | type |
+------+------------+------+
| 0 | 2020-06-02 | 1 |
| 0 | 2020-06-01 | 0 |
+------+------------+------+
希望这会有所帮助。
【讨论】:
【参考方案3】:在Events
中使用NOT EXISTS
仅返回按日期的最后一行:
SELECT ID, IFNULL(e.Type, 1) Type
FROM Objects o
LEFT JOIN (
SELECT e.Object, e.Type
FROM Events e
WHERE NOT EXISTS (
SELECT 1 FROM Events
WHERE Object = e.Object AND Date > e.Date
)
) AS e ON e.Object = o.ID
或:
SELECT
o.ID,
IFNULL((SELECT e.Type FROM Events e WHERE e.Object = o.ID ORDER BY e.Date DESC LIMIT 1), 1) Type
FROM Objects o
请参阅demo。 结果:
> ID | Type
> -: | ---:
> 0 | 1
> 1 | 1
【讨论】:
【参考方案4】:如果您有版本 8 或更高版本,您可以使用 row_number() 函数计算最后一行
select * from
(
select id,coalesce(type,1) type,coalesce(date,date(now())) as dt,
row_number() over (partition by o.id order by coalesce(date,date(now())) desc) rn
from objects o
left join events e on e.object = o.id
order by o.id,dt desc
) s
where rn = 1;
【讨论】:
以上是关于MySQL - 如何在 JOIN 中使用相关子查询的主要内容,如果未能解决你的问题,请参考以下文章
Mysql join with subquery join 使用相关名称