首先让我提供一些背景信息。假设我的任务状态为:完成或未完成。任务可以是未完成然后完成的,也可以是立即完成的。这些状态被保存。我想知道任务是否经历了这种不完整的状态。
/* Two possible states for a task, marked by a bit */
CREATE TABLE state (ID int unique not null, iscomplete bit not null);
INSERT INTO state (ID, iscomplete)
VALUES (1, 0), (2, 1);
/* Three tasks, 2nd yet incomplete, 1 and 3 complete */
CREATE TABLE task (ID int unique not null, curr_state int not null);
INSERT INTO task (ID, curr_state)
VALUES (1, 2), (2, 3), (3, 4);
/* All states for tasks, task 1 has had an incomplete state, 3 has not */
CREATE TABLE curr_state (ID int unique not null, task int not null, state int not null);
INSERT INTO curr_state (ID, task, state)
VALUES (1, 1, 1), (2, 1, 2), (3, 2, 1), (4, 3, 2);
STATE: TASK: CURR_STATE:
ID | IsComplete ID | Curr_state ID | Task | State
----+----------- ----+----------- ----+-------+-------
1 | 0 (False) 1 | 2 1 | 1 | 1
2 | 1 (True) 2 | 3 2 | 1 | 2
3 | 4 3 | 2 | 1
4 | 3 | 2
通过此查询,我几乎可以得到所需的信息,这是状态不完整或NULL
中有Through
的所有完整情况。
SELECT t.ID as Task, s.iscomplete as Complete, st.ID as Through
/* Get finished tasks */
FROM task t
JOIN curr_state c
ON t.curr_state = c.ID
JOIN state s
ON c.state = s.ID
/* JOIN to unfinished states */
LEFT JOIN curr_state cs
ON t.ID = cs.task
LEFT JOIN state st
ON cs.state = st.ID and st.iscomplete = 0
WHERE s.iscomplete = 1
-------- RESULT ---------
Task | Complete | Through
1 true 1
1 true (null)
3 true (null)
-------- DESIRED --------
Task | Complete | Through
1 true 1
3 true (null)
唯一的问题是,现在第一个任务有两次,首先是不完整状态,然后是NULL
。如何避免这种情况?
给我this。
第一个LEFT JOIN
是多余的,可以交换为简单的JOIN
。
答案 0 :(得分:2)
您可以使用OUTER APPLY
代替LEFT JOIN
:
SELECT t.ID as Task, s.iscomplete as Complete, through.ID as Through
/* Get finished tasks */
FROM task t
JOIN curr_state c ON t.curr_state = c.ID
JOIN state s ON c.state = s.ID
/* JOIN to unfinished states */
OUTER APPLY (
SELECT st.ID
FROM curr_state cs
JOIN state st ON cs.state = st.ID
WHERE st.iscomplete = 0 AND cs.task = t.ID
) AS through
WHERE s.iscomplete = 1