简体   繁体   中英

I want pull to data from customer table

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

Now my question is, I want to pull RT ,LT in cd1 to cd8 at any of the line. But if RT present in the one column LT should not come and if LT is there RT should not come in the result.

Expected result

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

The simplest approach would be this; the duplication is nasty but that's the price of a horrible data model.

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)
/

The first sub-query returns rows where one of the code columns has a value 'RT' and none have a value of 'LT' , and the second sub-query returns the complementary set.

This would be the simplest approach except that you have nulls in cd7 and alas not in does not play nice with null values. So this query only returns the row sno = 1 . We need to handle that:

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)
/ 

This query returns rows sno = 1 and sno = 3 , as required. LiveSQL demo

Simple version:

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 version:

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 for both queries.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM