SQL Downselect基于字段复制的查询结果

时间:2012-11-14 15:18:38

标签: sql oracle join union

我正在寻找SQL查询的一些帮助。 (我正在使用Oracle。)

我有一个包含2个不同选择状态的联合查询。结果数据如下所示:

Col1     Col2     Col3
XXX      ValA     Val1
XXX      ValB     Val2
YYY      ValA     Val1
YYY      ValA     Val2

在此设置中,Col1 = XXX是默认值,Col1 = YYY是实际值。实际值(YYY)应该优先于默认值。实际值通过第2列和第3列定义。

我希望将这些结果归结为以下内容:

Col1     Col2     Col3
XXX      ValB     Val2
YYY      ValA     Val1
YYY      ValA     Val2

请注意,第一行已删除...这是因为有一个实际值(第3行中的YYY)占用了默认值(XXX)。

有关如何处理此事的任何想法?

3 个答案:

答案 0 :(得分:2)

您想过滤掉col2和col3与XXX和其他值一起显示的所有行。

您可以使用分析函数在子查询中执行适当的计数来实现此过滤器:

select col1, col2, col3
from (select t.*,
             count(*) over (partition by col2, col3) as numcombos,
             sum(case when col1 = 'XXX' then 1 else 0 end) over (partition by col2, col3) as numxs
      from t
     ) t
where numcombos = numxs or (col1 <> 'xxx')

答案 1 :(得分:1)

我的直觉是使用分析函数:

select distinct 
       first_value(col1) 
          over (partition by col2, col3 
                order by case col1 
                when 'XXX' then 1 
                else 0 end asc) as col1,
       col2, 
       col3 
from table1

但是,如果表很大并且已建立索引,那么使用完全外连接解决此问题可能更好(这是可能的,因为只有两个可能的值):

select coalesce(rl.col1, dflt.col1) as col1, 
       coalesce(rl.col2, dflt.col2) as col2,
       coalesce(rl.col3, dflt.col3) as col3
from (select * from table1 where col1 = 'XXX') dflt
full outer join (select * from table1 where col1 <> 'XXX') rl
on dflt.col2 = rl.col2 and dflt.col3 = rl.col3;

[Solution in SQLFiddle]

答案 2 :(得分:0)

我认为你可以使用这样的技巧:

select
  case when
  max(case when col1<>'XXX' then col1 end) is null then 'XXX' else
  max(case when col1<>'XXX' then col1 end) end as col1, 
  col2,
  col3
from
  your_table
group by col2, col3

我将默认值转换为null,然后按col3分组。 null和值之间的最大值是您要查找的值。这适用于您的示例数据,但它可能不是您正在寻找的,它取决于您的实际数据。