查询以显示具有表中属性的特定值的行

时间:2018-04-06 16:19:55

标签: sql oracle

有两个表prereq和workorder。 Prereq具有属性类型和状态以及wonum,workorder有winum。现在我想要那些来自workorder的winum,如果type ='ABC'或type ='DEF'的先决条件存在,那么它应该只处于COMP状态。

Eg:
Workorder:
wonum
123
456
245

Prereq:
type   status   wonum
ABC     COMP     123
DEF     PENDING  123
TEST    WORKING  123
ABC     COMP     456
TEST    WORKING  456
ABC     COMP     245
DEF     COMP     245
TEST    WORKING  245

Output: 456, 245

解释:123既有先决条件ABC又有DEF,但是DEF正在等待,因此我不希望这个结果 456在COMP状态下只有ABC,因此结果有效 245在COMP状态中有两个先决条件,这也是有效的

我尝试了两种逻辑:

首先:

select * from workorder w inner join prereq p
on w.wonum=p.wonum
where (p.type ='ABC' and status='COMP')
or (p.type='DEF' and status='COMP')
result: this shows 123 as well in output which is incorrect

第二

select * from workorder w inner join prereq p
on w.wonum=p.wonum
where (p.type ='ABC' and status='COMP')
AND (p.type='DEF' and status='COMP')
result: this does not show 456 in output which again is incorrect

2 个答案:

答案 0 :(得分:0)

这是一种方式:

SELECT wonum
FROM prereq
WHERE type IN ('ABC','DEF')
GROUP BY wonum
HAVING COUNT(CASE WHEN Status = 'COMP' THEN 1 ELSE NULL END) > 0
   AND COUNT(CASE WHEN Status <> 'COMP' THEN 1 ELSE NULL END) = 0

不确定您是否需要加入WorkOrder,但如果您将其添加回来并为列别名,则不会有任何损害。

修改

包含除ABC,DEF之外没有先决条件或先决条件的工单的一种方法是UNION ALL

SELECT wonum
FROM prereq
WHERE type IN ('ABC','DEF')
GROUP BY wonum
HAVING COUNT(CASE WHEN Status = 'COMP' THEN 1 ELSE NULL END) > 0
   AND COUNT(CASE WHEN Status <> 'COMP' THEN 1 ELSE NULL END) = 0

UNION ALL

SELECT wonum
FROM workorder w
WHERE NOT EXISTS (SELECT *
                  FROM prereq p
                  WHERE p.wonum = w.wonum
                  AND p.type IN ('ABC','DEF'))

第二个查询将包含使用type IN ('ABC','DEF')的先决条件表中不存在的任何工单。这也将涵盖在prereqs表中根本不存在的工单。

答案 1 :(得分:0)

with
workorder (wonum) as (
select 123 from dual union all
select 456 from dual union all
select 245 from dual
),
prereq (typ,   status,   wonum) as (
select 'ABC',     'COMP',     123 from dual union all
select 'DEF',     'PENDING',  123 from dual union all
select 'TEST',    'WORKING',  123 from dual union all
select 'ABC',     'COMP',     456 from dual union all
select 'TEST',    'WORKING',  456 from dual union all
select 'ABC',     'COMP',     245 from dual union all
select 'DEF',     'COMP',     245 from dual union all
select 'TEST',    'WORKING',  245 from dual )
select * from 
(
  select distinct wonum from prereq
  where wonum not in (
    select wonum from prereq
    where typ in ('ABC', 'DEF') and status != 'COMP'
  )
) join workorder using (wonum)
;