MySQL - 如何在 JOIN 中使用相关子查询

MySQL - How to use a correlated subquery inside a JOIN

我有两个 table,ObjectsEvents

Objects 的结构如下:

ID | Password
-------------
0  | aaaa
1  | bbbb

事件的结构如下:

Object | Date       | Type
--------------------------
0      | 2020-06-01 | 0
0      | 2020-06-02 | 1

我想实现的是:对于每个ID,获取关联的最后一个事件类型。在上面的示例中,对象 0 将关联到 1,因为 12020-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 未知,但我真的想不出任何其他解决方案。因此我的问题是:如何在加入的 table?

的条件中使用外部 table 的属性

如有不明之处请告诉我,谢谢。

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

您可以尝试这样的操作:

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 |
+------+------------+------+

希望对您有所帮助。

Events 中使用 NOT EXISTS 至 return 仅最后一行日期:

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

如果您使用的是版本 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;