简体   繁体   中英

Concetating results from Oracle table with several criterias

This is a tough one. I've read about concatating values from multible rows in a table, but can't find anything on how to go about the task set before me. I'm not an oracle-man, and untill now have only made simple select queries, so I'm at a loss here.

In a huge oracle database table (severel hundred millions of rows) containing laboratory results, I need to select information on specific requisitions, that meet a specific criteria.

Criteria: For the same ReqNo, Analysis AB and C must be present with an answer, if they are, any instance of the answer to analysis X, Y or Z should be selected

Table contents:

ReqNo   Ana Answer
1       A   7
1       B   14
1       C   18
1       X   250
2       A   8
2       X   35
2       Y   125
3       A   8
3       B   16
3       C   20
3       Z   100
4       X   115
4       Y   355
5       A   6
5       B   15
5       C   22
5       X   300
5       Y   108
5       C   88

Desired result:

ReqNo   A   B   C   X   Y   Z
1      7    14  18  250     
3      8    16  20          100
5      6    15  22  300 108 88

leaving out ReqNo 2 and 4, since they don't meet the A/B/C criteria.

Is that even possible?

You may first filter the records that have all 3 (A,B and C) and then use PIVOT to convert them to columns for those which satisfy the criteria.

with req
AS
 (
   select reqno from t where ana IN ('A','B','C') 
    GROUP BY reqno HAVING
   count(DISTINCT  ana) = 3
 )
select * FROM
(
  select * from t where 
    exists ( select 1 from req r where t.reqno = r.reqno )
 )
    PIVOT(
          min(answer) for ana in ('A' as A, 'B' as B, 'C' as C,
                                  'X' as X, 'Y' as Y, 'Z' as Z)
           ) ORDER BY reqno;

Demo

I would just use conditional aggregation:

select reqno,
       max(case when Ana = 'A' then Answer end) as a,
       max(case when Ana = 'B' then Answer end) as b,
       max(case when Ana = 'C' then Answer end) as c,
       max(case when Ana = 'X' then Answer end) as x,
       max(case when Ana = 'Y' then Answer end) as y,
       max(case when Ana = 'Z' then Answer end) as z
from t
group by reqno
having sum(case when Ana = 'A' then 1 else 0 end) > 0 and
       sum(case when Ana = 'B' then 1 else 0 end) > 0 and
       sum(case when Ana = 'C' then 1 else 0 end) > 0 ;

Given that you don't seem to have duplicates, you can simplify the having to:

having sum(case when Ana in ('A', 'B', 'C') then 1 else 0 end) = 3

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