简体   繁体   中英

Alternative to a Filtered Sub-query

I have this query that works as desired, but it seems like there should be a better way to accomplish what I want:

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'

I am looking for a member whose membership ends on a certain date. The memberships table has start and end columns contain the dates that the membership is active. I only want to look at the last ending membership period, hence the MAX() and GROUP BY in the sub-query.

This could be rewritten using 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'

You could use a subquery... did this multiple ways in my head and settled with this:

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)

Edit: a faster approach that will limit the initial group to people who had a membership end on that date.

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM