sno name cd1 cd2 cd3 cd4 cd5 cd6 cd7 cd8
1 ram RL RL RL CD VF RT EE N
2 SAM RT LT RT LT RR RT N
3 VAN LT LT RR VV FF GG N
4 HH LT RT RR VV GG HH RT
现在我的问题是,我想将CD1中的RT,LT拉到任何一行的cd8。但是,如果在一列LT中出现的RT不应该出现,如果LT在那里,RT不应该出现在结果中。
预期结果
sno name cd1 cd2 cd3 cd4 cd5 cd6 cd7 cd8
1 ram RL RL RL CD VF RT EE N
3 VAN LT LT RR VV FF GG N
答案 0 :(得分:0)
最简单的方法就是这样;重复是令人讨厌的,但这是一个可怕的数据模型的代价。
select * from customers
where 'RT' in (cd1 ,cd2 ,cd3 ,cd4 ,cd5 ,cd6 ,cd7 ,cd8)
and 'LT' not in (cd1 ,cd2 ,cd3 ,cd4 ,cd5 ,cd6 ,cd7 ,cd8)
union all
select * from customers
where 'LT' in (cd1 ,cd2 ,cd3 ,cd4 ,cd5 ,cd6 ,cd7 ,cd8)
and 'RT' not in (cd1 ,cd2 ,cd3 ,cd4 ,cd5 ,cd6 ,cd7 ,cd8)
/
第一个子查询返回其中一个代码列的值为'RT'
而没有值为'LT'
的行,第二个子查询返回补充集。
这是最简单的方法,除了cd7
中有空值而且not in
不能使用空值。因此,此查询仅返回行sno = 1
。我们需要处理:
with cte as (
select sno,
name,
nvl(cd1, 'n/a') as cd1,
nvl(cd2, 'n/a') as cd2,
nvl(cd3, 'n/a') as cd3,
nvl(cd4, 'n/a') as cd4,
nvl(cd5, 'n/a') as cd5,
nvl(cd6, 'n/a') as cd6,
nvl(cd7, 'n/a') as cd7,
nvl(cd8, 'n/a') as cd8
from customers
)
select * from cte
where 'RT' in (cd1 ,cd2 ,cd3 ,cd4 ,cd5 ,cd6 ,cd7 ,cd8)
and 'LT' not in (cd1 ,cd2 ,cd3 ,cd4 ,cd5 ,cd6 ,cd7 ,cd8)
union all
select * from cte
where 'LT' in (cd1 ,cd2 ,cd3 ,cd4 ,cd5 ,cd6 ,cd7 ,cd8)
and 'RT' not in (cd1 ,cd2 ,cd3 ,cd4 ,cd5 ,cd6 ,cd7 ,cd8)
/
此查询根据需要返回行sno = 1
和sno = 3
。 LiveSQL demo
答案 1 :(得分:0)
简单版本:
select *
from customer
where case when 'RT' in (cd1, cd2, cd3, cd4, cd5, cd6, cd7, cd8) then 1 else 0 end
+ case when 'LT' in (cd1, cd2, cd3, cd4, cd5, cd6, cd7, cd8) then 1 else 0 end = 1
Unpivot
版本:
select *
from customer
join (select sno
from customer
unpivot (val for col in (CD1, CD2, CD3, CD4, CD5, CD6, CD7, CD8))
group by sno
having count(distinct(case val when 'RT' then 1 when 'LT' then 2 end)) = 1)
using (sno)
两个查询的