我有一张这样的表:
<table border="1" cellspacing="0" cellpadding="5">
<tr><td>ID</td><td>status</td><td>start_date</td><td>end_date</td></tr>
<tr><td>1</td><td>A</td><td>2015-01-01</td><td>2015-12-31</td></tr>
<tr><td>1</td><td>B</td><td>2016-01-01</td><td>NULL</td></tr>
<tr><td>2</td><td>C</td><td>NULL</td><td>2016-12-31</td></tr>
<tr><td>3</td><td>D</td><td>NULL</td><td>NULL</td></tr>
</table>
我必须在MySQL中执行一个触发器来更新主表的最后状态。
要执行此操作,我必须根据ID
和status
之间的时间段选择最后start_date
的{{1}},如果不知道则可以为NULL。< / p>
我写这个SQL语句测试:
end_date
是否有缩短方法来执行此操作?
实际上我想要一个能够捕获每个案例的WHERE子句(a = start_date,b = end_date):
SELECT *
FROM My_Table AS T
WHERE T.start_date Is Null AND
T.end_date In(SELECT MAX(end_date) FROM My_Table WHERE ID = T.ID)
OR
T.start_date In(SELECT MAX(start_date) FROM My_Table WHERE ID = T.ID) AND
T.end_date Is Null
OR
T.start_date In(SELECT MAX(start_date) FROM My_Table WHERE ID = T.ID) AND
T.end_date In(SELECT MAX(end_date) FROM My_Table WHERE ID = T.ID
);
答案 0 :(得分:2)
这是一个稍微简化的查询,它返回与您问题中的查询完全相同的结果集。它只使用两个子查询而不是四个(没有重复的子查询):
SELECT *
FROM My_Table AS T
WHERE
(T.start_date Is Null OR T.start_date = (SELECT MAX(start_date) FROM My_Table WHERE ID = T.ID)) AND
(T.end_date Is Null OR T.end_date = (SELECT MAX(end_date) FROM My_Table WHERE ID = T.ID)) AND
(T.start_date Is NOT Null OR T.end_date Is NOT Null)
;
请注意,它不包含a = NULL AND b = NULL
案例。要包括它,必须删除最后一个AND子句,即:
SELECT *
FROM My_Table AS T
WHERE
(T.start_date Is Null OR T.start_date = (SELECT MAX(start_date) FROM My_Table WHERE ID = T.ID)) AND
(T.end_date Is Null OR T.end_date = (SELECT MAX(end_date) FROM My_Table WHERE ID = T.ID))
;