NullPointerException
NullPointerException

Reputation: 3814

Fetching one to many relationship from same table

I have to pull one to many relationship data from the same table. The structure of the table is like

____________________________________
| CUSTOMER_ID | SUBSCRIPTION_NAME |
-------------------------------------
|  1          |  ABC              |
|  1          |  TNT              |
|  1          |  AMC              |
|  2          |  ABC              |
|  2          |  USA              |
|  3          |  TNT              |
|  3          |  AMC              |
-------------------------------------

I would like to get the output like

    | CUSTOMER_ID   |  SUBSCRIPTION_NAME |
    |  1            |  ABC,TNT,AMC       |
    |  2            |  ABC,USA           |
    |  3            |  TNT,AMC           |

Upvotes: 0

Views: 2820

Answers (2)

Dmitry Nikiforov
Dmitry Nikiforov

Reputation: 3038

Just few alternatives to LISTAGG:

SQL> with t (CUSTOMER_ID, SUBSCRIPTION_NAME)
  2  as (
  3  select 1,  'ABC' from dual union all
  4  select 1,  'TNT' from dual union all
  5  select 1,  'AMC' from dual union all
  6  select 2,  'ABC' from dual union all
  7  select 2,  'USA' from dual union all
  8  select 3,  'TNT' from dual union all
  9  select 3,  'AMC' from dual
 10  )
 11  SELECT   CUSTOMER_ID,
 12           RTRIM(
 13              XMLAGG (XMLELEMENT(e, SUBSCRIPTION_NAME||',') ORDER BY SUBSCRIPTION_NAME).EXTRACT('//text()')
 14           ,',') AS x
 15      FROM t
 16  GROUP BY CUSTOMER_ID
 17  /

CUSTOMER_ID X                                                                   
----------- ----------------------------------------                            
          1 ABC,AMC,TNT                                                         
          2 ABC,USA                                                             
          3 AMC,TNT                                                             

SQL> with t (CUSTOMER_ID, SUBSCRIPTION_NAME)
  2  as (
  3  select 1,  'ABC' from dual union all
  4  select 1,  'TNT' from dual union all
  5  select 1,  'AMC' from dual union all
  6  select 2,  'ABC' from dual union all
  7  select 2,  'USA' from dual union all
  8  select 3,  'TNT' from dual union all
  9  select 3,  'AMC' from dual
 10  )
 11  select customer_id,
 12  max(substr(sys_connect_by_path( SUBSCRIPTION_NAME, ','),2)) x from
 13  (
 14  select customer_id, SUBSCRIPTION_NAME, row_number() over(partition by customer_id order by null) rn
 15  from t
 16  )
 17  start with rn=1
 18  connect by prior customer_id = customer_id and rn = prior rn+1
 19  group by customer_id
 20  /

CUSTOMER_ID X                                                                   
----------- ----------------------------------------                            
          1 ABC,TNT,AMC                                                         
          2 ABC,USA                                                             
          3 TNT,AMC       

Upvotes: 0

Andrew G
Andrew G

Reputation: 2496

SELECT customer_id,
   LISTAGG(subscription_name, '; ') WITHIN GROUP (ORDER BY subscription_name) AS subscription_name
FROM subscription
GROUP BY customer_id
ORDER BY customer_id;

Order by is optional

Upvotes: 3

Related Questions