在MySQL中查找一对多关系中的最新或标记行

时间:2015-06-10 12:49:19

标签: mysql

很抱歉,如果标题很差,我试图从主表到相关表进行连接,只返回与相关表中已标记或最新行匹配的单行。

主要表格,我们称之为群组,有列:

id, name

相关表格,让我们称之为用户,有列:

id, group_id, email, default, updated_datetime

查询应返回单个'组,以及来自'用户'的匹配记录。默认值= 1(首选),或者如果没有行默认值= 1,则行为MAX(updated_datettime)。 '用户'将有1-n行with group.id = user.group_id。

示例结果:

group.id, group.name, user.email, user.default, user.updated_datetime
1, 'test', 'email', '0', '2015-06-10 12:00'
2, 'other', 'email', 1', '2015-06-08 10:00'

这两个表都包含大量数据,因此我更喜欢使用join而不是子查询来执行此操作。我知道如何使用子查询来完成它,但由于分组有多个条件,我在使用连接时遇到了麻烦。

我做别名很好,例如:

select a.* from (query) as a

我试图避免主要选择中的子查询,例如:

select group.id, group.name, (query) as user.id

谢谢!

1 个答案:

答案 0 :(得分:2)

首先,您需要在select中使用2个连接和IF()来选择默认用户或上次更新的用户。 然后,因为您想使用MAX()条件加入,所以需要子查询。

这样的事情可以让你走上正轨:

select group.id, if(default_user.id is not null, default_user.id, last_updated_user.id) as user_id
from group
left join user default_user on default_user.group_id = group.id and default_user.default = 1
join (
  select user.* from (
    select group_id, max(updated_datetime) as updated_datetime from user group by group_id
  ) as max_per_group join user using(group_id, updated_datetime)
) as last_updated_user on last_updated_user.group_id = group.id

但请注意,这不是一个快速查询,如果您需要经常这样做,您可能想要重构您的表。例如,您可以在default_user_id表格中添加外键last_updated_user_idgroup