[英]MySQL: select row only where closest to date has column value
I want to return all rows that were public in May (2019-05), so if a row was turned to draft (and not back to public) at any point before the end of May, I don't want it. 我想返回所有在5月(2019-05)公开的行,因此,如果在5月底之前的任何时候将某行转为草稿(而不是重新公开),则不需要。 For example: 例如:
id | post_id | status | date
-------------------------
1 | 1 | draft | 2019-03-25
2 | 1 | public | 2019-04-02
3 | 1 | draft | 2019-05-25
4 | 2 | draft | 2019-03-10
5 | 2 | public | 2019-04-01
6 | 2 | draft | 2019-06-01
The desired result for the above would return post_id 2
because its last status change prior to the end of May was to public
. 上面的预期结果将返回post_id 2
因为其5月底之前的最后状态更改已public
。
post_id 1
was put back in draft before the end of May, so it would not be included. 5月底之前将post_id 1
重新放回草稿中,因此不会包含在内。
I'm not sure how to use the correct join or sub-queries to do this as efficiently as possible. 我不确定如何使用正确的联接或子查询来尽可能高效地执行此操作。
You seem to want the status as of 2019-05-31. 您似乎想要截至2019-05-31的状态。 A correlated subquery seems like the simplest solution: 相关子查询似乎是最简单的解决方案:
select t.*
from t
where t.date = (select max(t2.date)
from t t2
where t2.post_id = t.post_id and
t2.date <= '2019-05-31'
);
To get the ones that are public, just add a WHERE
condition: 要获取公开的内容,只需添加WHERE
条件:
select t.*
from t
where t.date = (select max(t2.date)
from t t2
where t2.post_id = t.post_id and
t2.date <= '2019-05-31'
) and
t.status = 'public';
For performance, you want an index on (post_id, date)
. 为了提高性能,您需要在(post_id, date)
上建立索引。
You can also phrase this using a JOIN
: 您也可以使用JOIN
来表达这一点:
select t.*
from t join
(select t2.post_id, max(t2.date) as max_date
from t t2
where t2.date <= '2019-05-31'
group by t2.post_id
) t2
on t2.max_date = t.date
where t.status = 'public';
I would expect the correlated subquery to have better performance with the right indexes. 我希望相关的子查询在正确的索引下具有更好的性能。 However, sometimes MySQL surprises me. 但是,有时MySQL使我感到惊讶。
we need to determine whether 我们需要确定是否
post_id
is public
prior to the month May
(the subquery with max(date)), 每个post_id
的状态在May
(具有max(date)的子查询)之前是public
, post_id
exists with status not equals public
within the month May
, 在May
内,任何post_id
存在且状态不等于public
, post_id
satisfying the matter 2. 然后排除满足此要求的post_id
2。 So, you can use : 因此,您可以使用:
select distinct t1.post_id
from tab t1
where t1.post_id not in
(
select distinct t1.post_id
from tab t1
join
(
select post_id, max(date) as date
from tab
where '2019-05-01'> date
group by post_id ) t2
on t1.post_id = t2.post_id
where t1.status != 'public'
and t1.date < '2019-06-01'
and t1.date > '2019-04-30'
);
+---------+
| POST_ID |
+---------+
| 2 |
+---------+
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.