2011-06-09 66 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