SQL删除没有明确的重复记录

时间:2017-05-22 17:09:21

标签: sql oracle

这适用于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侧。我已经尝试了一些临时表,但我无法得到任何接近工作的东西,因为我需要有一些东西说“我返回了更多的那一行,其中一行是詹姆斯记录”。谢谢你的帮助。

2 个答案:

答案 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