2

I created this ORACLE SQL query that gives me all the data I need:

SELECT ci.record_no,
         ci.communication_no,
         ctt.description AS "TOPIC",
         ctc.description AS "CATEGORY",
         cc.sequence_no
    FROM communication_instance ci,
         communication_category cc,
         ct_category ctc,
         ct_topic ctt,
         ct_type ctp,
         department d,
         communication_record cr
   WHERE     ci.record_no = cc.record_no
         AND ci.record_no = cr.record_no
         AND cc.topic = ctc.topic
         AND cc.topic = ctt.code
         AND cc.category = ctc.category
         AND ci.communication_type = ctp.code
         AND ci.creator_department = d.code
         AND ci.record_no = '1565852'
ORDER BY 2  

The data output looks like this:

|RECORD_NO | COMMUNICATION_NO | TOPIC | CATEGORY | SEQUENCE_NO|

  1565852             1           Inter     Stat          1   
  1565852             1           Clien     Call          2   
  1565852             2           Inter     Stat          1   
  1565852             2           Clien     Call          2   
  1565852             3           Inter     Stat          1   
  1565852             3           Clien     Call          2  

Please note the following relationships:

  • 1 communication_no is 1 instance of the record_no (ie. there should only be 3 communication_no rows)
  • For every unique record_no, there can be multiple sequence_no's
  • Since multiple sequence_no's can exist for a single record_no, each communication_no would have 1 & 2 as their sequence_no's

I am trying to get the data to display the 3 unique communcation_no records, and have the topic, category and sequence_no's displayed in separate columns (instead of by rows). So the columns would become:

  • RECORD_NO
  • COMMUNICATION_NO
  • TOPIC_1
  • CATEGORY_1
  • SEQUENCE_NO_1
  • TOPIC_2
  • CATEGORY_2
  • SEQUENCE_NO_2

For example, communication_no = 1, would have 1 row and the fields would be (in order):

  • 1565852
  • 1
  • Inter
  • Stat
  • 1
  • Clien
  • Stat
  • 2

Is this possible?

4

1 回答 1

1

To achieve the desired result, as one of the approaches, you could use unpivot operator. Here is an example:

-- sample of data from your question
with t1(record_no, comunication_no, topic, category, sequence_no) as(
  select 1565852, 1, 'Inter', 'Stat', 1 from dual union all   
  select 1565852, 1, 'Clien', 'Call', 2 from dual union all   
  select 1565852, 2, 'Inter', 'Stat', 1 from dual union all
  select 1565852, 2, 'Clien', 'Call', 2 from dual union all   
  select 1565852, 3, 'Inter', 'Stat', 1 from dual union all   
  select 1565852, 3, 'Clien', 'Call', 2 from dual
),
t2 as(
   select case 
            when record_no =
                 lag(record_no) over(order by record_no)
            then null
            else to_char(record_no)
          end                  as record_no
        , case 
            when comunication_no =
                 lag(comunication_no) over(partition by record_no
                                           order by comunication_no)
            then null
            else to_char(comunication_no)
          end                  as comunication_no
        , topic
        , category  
        , to_char(sequence_no) as sequence_no 
        , to_char(sequence_no) as sequence_no_1      
    from t1 t
   where record_no = 1565852
     and comunication_no = 1
)
select case 
         when col in ('TOPIC', 'CATEGORY', 'SEQUENCE_NO')
         then col || '_' || sequence_no_1
         else col
       end  as col
     , val
  from t2
unpivot(
   val for col in ( record_no, comunication_no
                  , topic, category, sequence_no)
)

Result:

COL                   VAL
-------------------------------
RECORD_NO             1565852
COMUNICATION_NO       1
TOPIC_1               Inter
CATEGORY_1            Stat
SEQUENCE_NO_1         1
TOPIC_2               Clien
CATEGORY_2            Call
SEQUENCE_NO_2         2

8 rows selected

SQLFiddle Demo

EDIT

with t1(record_no, comunication_no, topic, category, sequence_no) as(
  select 1565852, 1, 'Inter', 'Stat', 1 from dual union all   
  select 1565852, 1, 'Clien', 'Call', 2 from dual union all   
  select 1565852, 2, 'Inter', 'Stat', 1 from dual union all
  select 1565852, 2, 'Clien', 'Call', 2 from dual union all   
  select 1565852, 3, 'Inter', 'Stat', 1 from dual union all   
  select 1565852, 3, 'Clien', 'Call', 2 from dual
), 
t2 as
(
  select to_char(record_no) as record_no
       , to_char(comunication_no) as comunication_no
       , topic
       , category
      , to_char(sequence_no) as sequence_no
      , to_char(sequence_no) as sequence_no_1
  from t1
 where record_no = 1565852
   and comunication_no = 1
)
select *
  from ( select record_no
              , case 
                  when col in ('TOPIC', 'CATEGORY', 'SEQUENCE_NO')
                  then col || '_' || sequence_no_1
                  else col
               end  as col
             , val
          from t2
        unpivot(
            val for col in (comunication_no, topic, category, sequence_no)
        )
     )
  pivot(
      max(val) for col in ('COMUNICATION_NO', 'TOPIC_1', 
                           'CATEGORY_1', 'SEQUENCE_NO_1',
                            'TOPIC_2','CATEGORY_2' ,
                            'SEQUENCE_NO_2')
)

Result:

RECORD_NO  'COMUNICATION_NO'  'TOPIC_1'  'CATEGORY_1'  'SEQUENCE_NO_1'  'TOPIC_2' 'CATEGORY_2'  'SEQUENCE_NO_2' 
-------------------------------------------------------------------------------------------------------------------  
1565852                1      Inter        Stat              1      Client          Call               2 

SQLFiddle

于 2013-09-19T09:09:58.543 回答