Oracle SQL查询使用大小写时,压缩空字段

时间:2015-12-01 15:12:13

标签: sql oracle

我有一张这样的表:

产品

id      group    old_new     object 

1         A         O         pen
2         A         N         house
3         B         O         dog
4         B         O         cat
5         C         N         mars
6         C         O         sun
7         C         N         moon
8         C         o         earth 

我想选择返回:

产品

   group   new_object   old_object 

     A        house      pen     
     B        null       dog
     B        null       cat
     C        mars       sun
     C        moon       earth 

如果我尝试:

select id, 
       case when old_new = 'N' then object end as new_object,
       case when old_new = 'O' then object end as old_object
from the_table
order by id;

我有8行,许多字段为null es:最后一行:

  group   new_object   old_object 

     C        mars       null
     c        null       sun
     C        moon       null
     c        null       earth

但是对于C组我只想要2排...... 不像其他查询'Oracle sql join same table ecc ...',因为这里不需要null结果

4 个答案:

答案 0 :(得分:1)

我将假设旧记录和新记录按照它们基于ID值出现的顺序进行配对。根据该假设,以下查询:

<SideNav>

除了示例数据部分(WITH DTA(ID, GRP, OLD_NEW, OBJECT) AS ( select 1, 'A', 'O', 'pen' from dual union all select 2, 'A', 'N', 'house' from dual union all select 3, 'B', 'O', 'dog' from dual union all select 4, 'B', 'O', 'cat' from dual union all select 5, 'C', 'N', 'mars' from dual union all select 6, 'C', 'O', 'sun' from dual union all select 7, 'C', 'N', 'moon' from dual union all select 8, 'C', 'O', 'earth' from dual ), dta2 as ( select dta.* , row_number() over (partition by GRP, old_new order by id) rn from dta ) select coalesce(n.grp, o.grp) grp , n.object new_object , o.object old_object from (select * from dta2 where old_new = 'N') n full join (select * from dta2 where old_new = 'O') o on n.grp = o.grp and n.rn = o.rn; )之外,此脚本首先使用分析函数ROW_NUMBER()添加由group和old_new列分区的序列号。然后,它在dta2子因子查询的两个内联视图上执行完全外部连接,一个用于thr旧对象,另一个用于新对象。结果,至少对于这个数据集是:

with dta

答案 1 :(得分:1)

在第一步中,为您的组分配chnage的索引(IDX)。我按照ID使用订单,但这是在你身上。重要的是旧的和新的价值观与GRP和IDX是唯一的联系。

下一步让PIVOT为你工作(我使用@Sentinel的数据,thx!)

WITH DTA(ID, GRP, OLD_NEW, OBJECT) AS (
  select 1, 'A', 'O', 'pen'   from dual union all
  select 2, 'A', 'N', 'house' from dual union all
  select 3, 'B', 'O', 'dog'   from dual union all
  select 4, 'B', 'O', 'cat'   from dual union all
  select 5, 'C', 'N', 'mars'  from dual union all
  select 6, 'C', 'O', 'sun'   from dual union all
  select 7, 'C', 'N', 'moon'  from dual union all
  select 8, 'C', 'O', 'earth' from dual
), DTA2 as (
SELECT 
ROW_NUMBER() OVER (PARTITION BY GRP,OLD_NEW order by ID) as IDX,
GRP, OLD_NEW, OBJECT
from DTA
)
select * from DTA2
PIVOT (max(OBJECT) OBJECT  for (OLD_NEW) in 
('N' as "NEW",
'O' as "OLD"
))
order by GRP;

结果

IDX, GRP, NEW_OBJECT, OLD_OBJECT
1   A   house   pen
1   B           dog
2   B           cat
2   C   moon    earth
1   C   mars    sun

答案 2 :(得分:0)

提供

  • 每个旧的最多只有一个新对象
  • 没有旧对象,没有新对象,
  • 任何群组最多只有一个旧对象(对于您的示例数据,为true,但在评论中您表明您对此类解决方案也感兴趣)

可以使用比一般情况更简单的查询:

select
    old.group as group, new.object as new_object, old.object as old_object
from
    (select group, object from my_table where old_new = 'O') old
        left join
    (select group, object from my_table where old_new = 'N') new
        on (old.group = new.group)

答案 3 :(得分:0)

这是使用PIVOT获得结果的替代方案:

with items as (select 1 id, 'A' grp, 'O' old_new, 'pen' obj from dual union all
               select 2 id, 'A' grp, 'N' old_new, 'house' obj from dual union all
               select 3 id, 'B' grp, 'O' old_new, 'dog' obj from dual union all
               select 4 id, 'B' grp, 'O' old_new, 'cat' obj from dual union all
               select 5 id, 'C' grp, 'N' old_new, 'mars' obj from dual union all
               select 6 id, 'C' grp, 'O' old_new, 'sun' obj from dual union all
               select 7 id, 'C' grp, 'N' old_new, 'moon' obj from dual union all
               select 8 id, 'C' grp, 'O' old_new, 'earth' obj from dual)
-- end of mimicking your items table with data in it. See SQL below:
select grp,
       new_object,
       old_object
from   (select grp,
               old_new,
               obj,
               row_number() over (partition by grp, old_new order by id) rn
        from   items)
pivot (max(obj)
        for old_new in ('N' new_object,
                                'O' old_object))
order by grp,
         rn;

GRP NEW_OBJECT OLD_OBJECT
--- ---------- ----------
A   house      pen       
B              dog       
B              cat       
C   mars       sun       
C   moon       earth