我有两个表A
和B
。这两个表都由Psslno
预先键入,B
是A
中的主键和B
中的外键。我想要的是,我需要表Pid
中的记录
其中B
不应以字符S为后缀,同时Pssslno
表status
下的所有记录都在工作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/>
那是不是?
答案 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