这适用于Oracle DB SQL(pl / sql)
我有一个三列数据表(为了参数)。 我需要删除返回的行,其中columnA和columnB匹配表中的另一个记录,columnC等于'james'。但是如果columnC等于'james'和columnA,则columnB与结果集中的任何其他行都不匹配,请保留它。
ColumnA ColumnB ColumnC
_______________________
45 blue John <-Keep
45 blue James <-Remove
32 Red John <-Keep
32 Red James <-Remove
12 Yellow James <-Keep
结果集将是:
ColumnA ColumnB ColumnC
_______________________
45 blue John
32 Red John
12 Yellow James
显然,真实数据更复杂,列数更多。我的背景是在等式的C#侧而不是Oracle DB侧。我已经尝试了一些临时表,但我无法得到任何接近工作的东西,因为我需要有一些东西说“我返回了更多的那一行,其中一行是詹姆斯记录”。谢谢你的帮助。
答案 0 :(得分:4)
这是使用窗口函数获取匹配记录计数的一种方法:
SELECT
columnA,
columnB,
columnC
FROM
(
SELECT
columnA,
columnB,
columnC,
COUNT(*) OVER (PARTITION BY columnA, columnB) as rcount
FROM table
) sub
WHERE
(sub.rcount = 2 AND columnC = 'John')
OR sub.rcount = 1;
答案 1 :(得分:2)
您可以使用带count
的分析case
函数检查给定的columnA和columnB组合是否存在非“James”记录:
with your_table (ColumnA ,ColumnB ,ColumnC) as (
select 45, 'blue' ,'ABC' from dual union all
select 45, 'blue' ,'Jimmy' from dual union all
select 45, 'blue' ,'John' from dual union all
select 45, 'blue' ,'James' from dual union all
select 32, 'Red' ,'John' from dual union all
select 32, 'Red' ,'James' from dual union all
select 12, 'Yellow' ,'James' from dual
)
--Sample data ends. Solution starts below--
select ColumnA ,ColumnB ,ColumnC
from (
select t.*,
case when count(case when columnC <> 'James' then 1 end) over (
partition by columnA,
columnB
) > 0 then 1 else 0 end as flag
from your_table t
)
where flag = 0
or columnC <> 'James'
输出:
COLUMNA COLUMNB COLUMNC
12 Yellow James
32 Red John
45 blue John
45 blue Jimmy
45 blue ABC