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中的任何一行。但是,如果RT出现在一列中,则LT不应该出现,如果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发布于 2017-12-29 16:04:32
最简单的方法是这样的;复制是令人讨厌的,但这是可怕的数据模型的代价。
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
https://stackoverflow.com/questions/48018513
复制相似问题