自我加入没有双重结果集?

时间:2011-09-07 11:51:23

标签: sql database oracle

(id,name,dept_name)有一些重复(出现两次或多次)组合。注意:dept_name可以为空,因此该列中通常会有一些空值。

我试图得到重复(id,name,dept_name)组合的结果,其中一个记录有一个空mgr_id或sal但是同一个重复组合的另一个记录有一个非null mgr_id或sal。

这是我到目前为止所做的:

 select t1.id, t1.name, t1.dept_name, t1.mgr_id, t2.mgr_id, t1.sal, t2.sal from employee t1
    inner join employee t2 on t2.id = t1.id and t2.name = t1.name
    where t1.id in
    (select id from 
    (select id, name, dept_name, count(*) from employee
    group by id, name, dept_name
    having count(*) > 1))
    and (nvl(t1.mgr_id,0) <> nvl(t2.mgr_id,0) 
    or nvl(t1.sal,0) <> nvl(t2.sal,0)) 
    and t1.mgr_id is not null ;

如果我在查询中没有留下最后一行“并且t1.mgr_id不为空”,我实际上会两次收到相同的结果集(我不想要)。但是,我需要一些方法来合并(t1.sal is not null)子句,以便两次不能获得相同的结果集。

另外,请注意我没有PK或序列号列,我可以去: t1.seq_no <> t2.seq_no

5 个答案:

答案 0 :(得分:2)

您不能只将过滤器添加到OR?:

 select t1.id, t1.name, t1.dept_name, t1.mgr_id, t2.mgr_id, t1.sal, t2.sal from employee t1
    inner join employee t2 on t2.id = t1.id and t2.name = t1.name
    where t1.id in
    (select id from 
    (select id, name, dept_name, count(*) from employee
    group by id, name, dept_name
    having count(*) > 1))
    and ((nvl(t1.mgr_id,0) <> nvl(t2.mgr_id,0) AND t1.mgr_id is not null) 
    or (nvl(t1.sal,0) <> nvl(t2.sal,0) AND t1.sal is not null));

答案 1 :(得分:1)

您可以使用ROWID来区分行:

and t1.ROWID <> t2.ROWID

答案 2 :(得分:1)

如果有效,请试试这个......

select id,name,dept_name 
from employee 
where id in (select a.id 
             from employee a 
             where (a.sal is NULL or a.mgr_id is NULL) 
and a.id in (select b.id 
             from employee b 
             where b.sal is not NULL or b.mgr_id is not NULL));

答案 3 :(得分:1)

这是因为你有4种情况。

  • sal null,dept null

  • sal null,dept nonnull

  • sal nonnull,dept null

  • sal nonnull,dept nonnull

您只有两组要比较的列。

不知怎的,你会得到重复的。

作为一种hibrid解决方案,您可以尝试:

select distinct t1.id, t1.name, t1.dept_name, t1.mgr_id, t2.mgr_id, t1.sal, t2.sal from employee t1
    inner join employee t2 on t2.id = t1.id and t2.name = t1.name
    where t1.id in
    (select id from 
    (select id, name, dept_name, count(*) from employee
    group by id, name, dept_name
    having count(*) > 1))
    and (nvl(t1.mgr_id,0) <> nvl(t2.mgr_id,0) 
    or nvl(t1.sal,0) <> nvl(t2.sal,0)) ;

(注意截然不同)

或者,您可以使用:

select distinct t1.id, t1.name, t1.dept_name, t1.mgr_id 
from employee t1
order by 1, 2, 3, 4

你会看到行之间的区别。

答案 4 :(得分:1)

我创建了以下帖子,以显示我通常在同一个表中找到重复项。

http://tsells.wordpress.com/2010/01/08/sql-query-trick-to-find-duplicate-records/

我找到了我想要找到的标准(下面示例中的MyName),然后使用另一个字段来确定哪些值不相等(通常是ID字段)。

select 
t1.ID,
t1.MyName,
t2.MyName,
t2.ID
from
Table t1 
inner join Table t2 on t1.MyName = t2.MyName and t1.ID <> t2.ID

请注意,这可能会返回看似重复的内容 - 但稍微调整查询可以解决这个问题。此外,我通常使用它来检查数据与生产查询。