我想从客户表中提取数据

时间:2017-12-29 06:38:39

标签: sql oracle

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

2 个答案:

答案 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 = 1sno = 3LiveSQL 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)
两个查询的

SQLFiddle demo