SQL subselect filtering based on multiple sub-rows

守給你的承諾、 提交于 2019-12-12 04:17:30

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!