问题
I have two tables, and want to extract certain columns from the first, based on 'child' data from the second.
- I'm using SQL Anywhere 12
Table 1) Lets call it Projects
proj_id | Name --------+--------- 10 | Proj_1 20 | Proj_2 30 | Proj_3 40 | Proj_4
Table 2) Lets call this one tasks
proj_id | task_id | Status --------+---------+----------- 10 | 1 | Ready 10 | 2 | Cancelled 10 | 3 | Ready 20 | 1 | Complete 20 | 2 | Ready 30 | 1 | Ready 30 | 2 | Not Ready 30 | 3 | Complete 40 | 1 | Ready 40 | 2 | Ready
Want I want to do is find out which 'projects' have 'tasks' that are 'ready'.
The tricky part here is that it is OK if other tasks are Complete, but its not OK if they are anything other than complete or ready
So in other words the output should look like this:
Name | Status -------+-------- Proj_2 | Ready Proj_4 | Ready
What I don't want in the result set is to see Proj_1 (a task was cancelled) or Proj_3 (a task is not ready)
I'm not posting any SQL, because I'm not sure if this is even possible....
Normally I would do something like this in C++ in 2 multiple statements, but in this case I need it in a single statement, as I need to pass the data to a third party printing program.
回答1:
There are several ways to approach this type of query. I like to use aggregation with a having
clause, because it is quite flexible and all the logic goes in the having
clause:
select t.proj_id
from tasks t
group by t.proj_id
having sum(case when status = 'ready' then 1 else 0 end) > 0 and
sum(case when status not in ('complete, 'ready') then 1 else 0 end) = 0;
Each condition in the having
clause counts the number of tasks that have a particular condition. The first counts the number of ready tasks, and the > 0
says there is at least one. The second counts the number of non-ready, non-complete counts. The = 0
says there are none.
回答2:
NOT EXISTS
solution, i.e. return a project if it has a ready task, and no task other than ready and complete:
select p.*
from Projects p
join tasks t on p.proj_id = t.proj_id
where t.Status = 'ready'
and not exists (select * from tasks t2
where t2.proj_id = t.proj_id
and t2.Status NOT IN ('ready', 'Complete'))
来源:https://stackoverflow.com/questions/34789990/sql-subselect-filtering-based-on-multiple-sub-rows