Oracle sql - 根据几列选择不同的列

时间:2014-06-16 08:56:04

标签: sql database oracle oracle11g relational-database

我有一个选择查询,例如

select a, b, c, d, e, f, g, h, i, j from sample_table

我需要从这张表中获得不同的记录集,所以我把

select distinct a, b, c, d, e, f, g, h, i, j from sample_table

但是,重复列仍然在结果集中,因为i,j与result,result1,RESULT之类的微小变化不同。我需要摆脱这个微小的变化,但想把它放在结果集中。

如何选择a,b,c,d,e,f,g,h的不同列,并在结果集中也有i,j。

4 个答案:

答案 0 :(得分:2)

您可以使用分析函数执行此操作:

select a, b, c, d, e, f, g, h, i, j
from (select st.*,
             row_number() over (partition by a, b, c, d, e, f, g, h order by a) as seqnum
      from sample_table
     ) st
where seqnum = 1;

这可确保ij的值来自同一行。

答案 1 :(得分:2)

SELECT DISTINCT删除重复的行。

如果认为某些值是"相同"无论是在列内还是在两列之间,在包含它们的行可以被DBMS视为重复之前,您必须使它们实际上相同。

在列中,您可以将每个可能的变体转换为一个特定的变体。这称为转换为规范或普通形式。

select distinct ...,
    case i when "result1" then "result"
        else "RESULT" then "result"
        else "result" then "result"
        else "dOg" then "dog"
        ...
    end as i,
    convert_to_upper_case(j) as j,
    correct_spelling(k) as k
from sample_table

如果要考虑跨列的值相同,则可以以这种方式转换它们并比较规范形式。或者,您可以编写一个比较它们的表达式,并输出两个列的单个值。这被称为等价关系。

select distinct ...,g,h,i, i as j
from sample_table
where ...
AND my_canonical_form(g) = my_canonical_form(h)
AND equivalent_according_to_me(i,j)

如果j实际上不应该与我的不同,那么可以用于生成sample_table:

select distinct ..., t.i, t.i as j -- no u.j
from t,u where ... and close_enough(t.i,u.j)

想法是canonical_form(x)= canonical_form(y)恰好在等效(x,y)时。

如果需要,您可以保留i和j列,也可以删除。

答案 2 :(得分:1)

可能你可以试试:

select distinct a, b, c, d, e, f, g, h, min(upper(i)) i, min(upper(j)) j from sample_table
group by a, b, c, d, e, f, g, h;

您可以考虑使用min或max结合子字符串,上限,下限或适合您的要求。

正如alex poole指出的那样,您还可以考虑使用带有时间戳的列,以便最新或最早的记录可以显示在结果集中。

答案 3 :(得分:0)

除了Nishanthi Grashia之外,如果你必须显示不同列的所有值,你可以使用listagg作为聚合函数:

select same1,same2,same3,same4,same5,same6,same7,same8, 
       listagg(diff1, ',') within group (order by 1,2,3,4,5,6,7,8)
     , listagg(diff2, ',') within group (order by 1,2,3,4,5,6,7,8) from (      
            select 1 as same1, 2 as same2 ,3 as same3, 4 as same4,5 as same5,6 as same6,7 as same7, 8 as same8,'m' as diff1,'n' as diff2 from dual
            union
            select 1,2,3,4,5,6,7,8,'n','o' from dual
            union
            select 2,3,4,5,6,7,8,9,'p','q' from dual
            union
            select 2,3,4,5,6,7,8,9,'p','x' from dual
) qry1 group by same1,same2,same3,same4,same5,same6,same7,same8