查询以过滤具有相同非主键值的行,然后从Oracle中的结果中排除具有另一个空列的记录

问题描述 投票:-1回答:4

表Mytable的示例数据

+----------+--------+----------+
|   BPT    |   BC   |    ST    |
+----------+--------+----------+
| NH       | AB360  | PTOTST   |
| MEMODMHF | AAAAA  | PTOTST   |
| NH       |        | PTOTST   |
| NH       |  ABH6G | PTOTSTCH |
| NH       |        |  PT01    |
| NH       | ABH6G  | PT04     |
| NH       |        | PT04     |
+----------+--------+----------+

使用值NH过滤BPT列

+------+--------+----------+
| BPT  |   BC   |    ST    |
+------+--------+----------+
| NH   | AB360  | PTOTST   |
| NH   |        | PTOTST   |
| NH   |  ABH6G | PTOTSTCH |
| NH   |        |  PT01    |
| NH   | ABH6G  | PT04     |
| NH   |        | PT04     |
+------+--------+----------+

过滤BC列,其值为空或ABH6G

+------+--------+----------+
| BPT  |   BC   |    ST    |
+------+--------+----------+
| NH   |        | PTOTST   |
| NH   |  ABH6G | PTOTSTCH |
| NH   |        |  PT01    |
| NH   | ABH6G  | PT04     |
| NH   |        | PT04     |
+------+--------+----------+

对于重复ST,排除BC为空的记录

+------+--------+----------+
| BPT  |   BC   |    ST    |
+------+--------+----------+
| NH   |        | PTOTST   |
| NH   |  ABH6G | PTOTSTCH |
| NH   |        |  PT01    |
| NH   | ABH6G  | PT04     |
+------+--------+----------+

下面提到的我的示例查询无效。如何实现此目的。

SELECT
  T1.BPT,
  T1.BC,
  T1.ST
FROM Mytable T1,
     Mytable T2
WHERE T1.BEN_PROD_TYP_CD IN ('NH')
AND ((T1.ST = T2.ST
AND T1.BC = 'ABH6G')
OR (T1.ST <> T2.ST
AND (T1.BC = 'ABH6G'
OR T1.BC IS NULL)));
sql oracle
4个回答
2
投票

实现结果的一种方法是使用row_number()

select t.BPT, t.BC, t.ST from
(
select t1.*, row_number() over(partition by st order by BC asc) as rn 
from MyTable t1
where t1.BPT = 'NH'
and (t1.BC = 'ABH6G' or t1.BC is null)
) t
where t.rn = 1

结果:

+-----+-------+----------+
| BPT |  BC   |    ST    |
+-----+-------+----------+
| NH  | NULL  | PTOTST   |
| NH  | ABH6G | PTOTSTCH |
| NH  | NULL  | PT01     |
| NH  | ABH6G | PT04     |
+-----+-------+----------+

DEMO


0
投票

比如说

with
  d as (select bpt, bc, coalesce(bc, '<<spaces>>') bcc, st from MyTable),
  m as (select bcc from d group by bcc having count(*) > 1)
select d.bpt, max(d.bc) bc, d.st
from d, m
where d.bpt = 'NH'
and d.bcc = m.bcc
group by st, bpt

SQL Fiddle for this


0
投票

试试这个样本:

Select * from [Mytable]
Where BPT = 'NH' and BC = 'ABH6G'
union
Select * from [Mytable]
Where BPT = 'NH' and BC = ''
And BPT+BC+ST not in (select BPT + '' + ST from [Mytable]
Where BPT = 'NH' and BC = 'ABH6G')

0
投票

我认为没有必要为你的要求自我加入....

SELECT DISTINCT
  T1.BPT,
  T1.BC,
  T1.ST
FROM Mytable T1
WHERE T1.BPT IN ('NH')
AND (T1.BC = 'ABH6G'
OR T1.BC IS NULL);

此致,Saravanan

© www.soinside.com 2019 - 2024. All rights reserved.