【问题标题】:Eliminating duplicate rows with null values using with clause使用 with 子句消除具有空值的重复行
【发布时间】:2019-07-13 14:45:33
【问题描述】:

我们如何通过使用 with 子句语句仅选择在某个字段中具有值的那些来消除重复?

查询是这样的:

with x as (--queries with multiple join tables, etc.)
select distinct * from x

下面的输出:

Com_no   Company      Loc    Rewards
1         Mccin      India      50
1         Mccin      India
2         Rowle      China      18
3         Draxel     China      11
3         Draxel     China  
4         Robo       UK          

如您所见,我得到了重复的记录。我想摆脱不唯一的空值。也就是说,Robo 是独一无二的,因为它在 Rewards 中只有 1 条记录为空值,所以我想保留它。

我试过了:

 with x as (--queries with multiple join tables, etc.)
 select distinct * from x where Rewards is not null

当然这是不对的,因为它也摆脱了4 Robo UK

预期的输出应该是:

1         Mccin      India      50
2         Rowle      China      18
3         Draxel     China      11 
4         Robo       UK      

【问题讨论】:

  • 预期的输出应该是什么?
  • @VamsiPrabhala 嗨,我添加了预期的输出。想知道我们是否仍然可以使用并从 with 子句 population 中选择

标签: sql oracle distinct common-table-expression distinct-values


【解决方案1】:

问题是您将这些行称为重复行,但它们不是重复行。他们是不同的。因此,您要做的是排除 Rewards 为空的行,除非没有任何非空值的行,然后选择不同的行。所以像:

select distinct * 
from x a
where Rewards is not null 
or (Rewards is null and not exists (select 1 from x b where a.Com_no = b.Com_no 
    and b.Rewards is not null)

现在您的 Robo 行仍将包括在内,因为 x 中没有针对 Robo 的行,其中 Rewards 不为空,但其他具有空奖励的公司的行将被排除,因为它们没有空行。

【讨论】:

  • 对不起,这对我不起作用。它不包括机器人
  • 抱歉。已编辑 SQL。
【解决方案2】:

这是一个优先级查询。一种方法是使用row_number()。如果每个Com_no/Company/Loc 只需要一个值,那么:

select x.*
from (select x.*,
             row_number() over (partition by Com_no, Company, Loc order by Rewards nulls last) as seqnum
      from x
     ) x
where seqnum = 1;

甚至:

select Com_no, Company, Loc, max(Rewards)
from x
group by Com_no, Company, Loc;

【讨论】:

  • 只要要求返回 com_no、company 和 Loc 的最大值,这些就可以工作。但这不是规定的要求。 “重复”不包括奖励栏吗?换句话说,如果印度有一行奖励值为 10,是否应该将其包含在结果中或不包含@BFF?
猜你喜欢
  • 2023-03-27
  • 2014-02-14
  • 2018-04-27
  • 1970-01-01
  • 2018-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多