如何通过比较oracle

时间:2018-03-13 15:33:16

标签: .net oracle

我有两个表AB。这两个表都由Psslno预先键入,BA中的主键和B中的外键。我想要的是,我需要表Pid中的记录 其中B不应以字符S为后缀,同时Pssslnostatus下的所有记录都在工作Psslno 1000(大于100)。如何获取得到这个 表B Pssslno 1100中给出的样本失败,因为表A中的一个记录具有状态80。Pssslno 1200满足,因为Pid不后缀S和{ 所有都在表A(> 100)中进行。Psslno 1300失败,因为Pid 101S后缀为S,Sslno Sid tech status height Psslno 100 89 G 80 11 1000 101 91 U 110 11 1000 102 93 L 110 11 1000 ------------------------------- 106 98 G 110 34 1100 107 99 U 118 34 1100 -------------------------------- 109 101 G 110 54 1200 110 102 U 110 54 1200 111 103 L 118 54 1200 -------------------------------- 112 105 G 110 54 1300 113 106 U 110 54 1300 114 107 L 118 54 1300 满足 表A如下所示

 Psslno   Pid     Location    Type

 1000      89    AJM         Mic  
 1100      98    SHJ         MAC
 1200      101S   DBB         LAC
 1300      105    ABB         SAC

表B如下所示

SELECT a.*
  FROM B a
  INNER JOIN A b
  ON a.Psslno   =b.Psslno   
  WHERE b.status>100
  AND a.Pid NOT LIKE'%S%'

我做了什么查询

<archived/>

那是不是?

1 个答案:

答案 0 :(得分:2)

您需要的是反加入。如果列NOT IN在表A中不可为空,则可以使用psslno条件更简单地编写它。

select psslno
from   b
where  pid not like '%S'
  and  not exists ( 
                    select *
                    from   a
                    where  psslno  = b.psslno
                      and  status <= 100
                  )
;

编辑根据OP澄清 - 他需要从上面的查询返回psslno的两个表中检索所有信息...

执行此操作的一种(有效)方法是对MIN()使用分析函数status,按psslno分区:

with
  a ( sslno, sid, tech, status, height, psslno ) as (
    select 100,  89, 'G',  80, 11, 1000 from dual union all
    select 101,  91, 'U', 110, 11, 1000 from dual union all
    select 102,  93, 'L', 110, 11, 1000 from dual union all
    select 106,  98, 'G', 110, 34, 1100 from dual union all
    select 107,  99, 'U', 118, 34, 1100 from dual union all
    select 109, 101, 'G', 110, 54, 1200 from dual union all
    select 110, 102, 'U', 110, 54, 1200 from dual union all
    select 111, 103, 'L', 118, 54, 1200 from dual union all
    select 112, 105, 'G', 110, 54, 1300 from dual union all
    select 113, 106, 'U', 110, 54, 1300 from dual union all
    select 114, 107, 'L', 118, 54, 1300 from dual
  ),
  b ( psslno, pid, location, type ) as (
    select 1000, '89'  , 'AJM', 'Mic' from dual union all  
    select 1100, '98'  , 'SHJ', 'MAC' from dual union all
    select 1200, '101S', 'DBB', 'LAC' from dual union all
    select 1300, '105' , 'ABB', 'SAC' from dual
  )
-- End of input data FOR TESTING ONLY (not part of the solution).
-- SQL query begins BELOW THIS LINE; use your actual table and column names.
select   q.sslno, q.sid, q.tech, q.status, q.height, q.psslno,
         b.pid, b.location, b.type
from     ( select a.*, min(status) over (partition by psslno) as min_status
           from   a
         ) q
         inner join b on q.psslno = b.psslno
where    q.min_status > 100
  and    b.pid not like '%S'
order by q.sslno    -- If needed.
;

<强>输出

SSLNO SID TECH STATUS HEIGHT PSSLNO PID  LOCATION TYPE
----- --- ---- ------ ------ ------ ---- -------- ----
  106  98 G       110     34   1100 98   SHJ      MAC
  107  99 U       118     34   1100 98   SHJ      MAC
  112 105 G       110     54   1300 105  ABB      SAC
  113 106 U       110     54   1300 105  ABB      SAC
  114 107 L       118     54   1300 105  ABB      SAC