0

我正在寻找有关 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)。

关于如何解决这个问题的任何想法?

4

3 回答 3

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')
于 2012-11-14T15:28:19.407 回答
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;

[SQLFiddle 中的解决方案]

于 2012-11-14T18:08:56.503 回答
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 和 value 之间的最大值是您要查找的值。这适用于您的示例数据,但它可能不完全是您正在寻找的,这取决于您的真实数据如何。

于 2012-11-14T15:27:09.873 回答