2011-06-09 69 views
0

我有这个疑问,它作为期望的,但是看起来应该有更好的方式来完成我想要的:替代的滤波的子查询

SELECT `x`.* 
FROM (
    SELECT `m`.`id`, 
     `m`.`email`, 
     MAX(`s`.`end`) AS `max_end` 
    FROM `members` AS `m` 
    INNER JOIN `memberships` AS `s` 
     ON `m`.`id` = `s`.`member_id` 
    GROUP BY `m`.`id`, 
     `m`.`email` 
) AS `x` 
WHERE `x`.`max_end` = '2010-02-28 23:59:59' 

我要寻找其成员资格的成员在某个日期结束。 memberships表包含startend列包含成员资格处于活动状态的日期。我只想查看最后的结束会员资格期,因此子查询中的MAX()GROUP BY

+2

神圣的蝙蝠侠.. – Fosco 2011-06-09 17:04:28

+0

@Fosco - 你让我笑了。谢谢! – Sonny 2011-06-09 17:18:17

回答

2

这可以通过使用having被改写:

SELECT `m`.`id`, 
    `m`.`email` 
FROM `members` AS `m` 
INNER JOIN `memberships` AS `s` 
    ON `m`.`id` = `s`.`member_id` 
GROUP BY `m`.`id`, 
    `m`.`email` 
HAVING MAX(`s`.`end`) = '2010-02-28 23:59:59' 
+0

啊,是的,我忘记了'HAVING'。是否有性能差异? – Sonny 2011-06-09 17:08:01

+1

就你的情况而言,我希望MySQL能够在生成所有行后进行过滤而不是过滤......因此可能。 – 2011-06-09 17:09:27

1

你可以使用子查询......的确在我的头上这多种方式和解决与此:

select m.* 
from members m 
where '2010-02-28 23:59:59' = (select MAX(x.end) 
           from memberships x 
           where x.member_id = m.id) 

编辑:更快的方法这将限制最初的小组成员在该日期结束会员。

select m.* 
from members m 
join memberships s on m.id = s.member_id 
    and s.end = '2010-02-28 23:59:59' 
where s.end = (select MAX(x.end) 
       from memberships x 
       where x.member_id = m.id) 
+2

这会变慢 - 它会为每个成员执行一个嵌套的子查询。 – 2011-06-09 17:10:08