我有一张这样的表:
产品
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结果
答案 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)
提供
可以使用比一般情况更简单的查询:
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