简体   繁体   中英

Group by with null columns in oracle

I want to get group of column values with comma separated including Null values of Group by columns. Group by treats NUll values as separate group.

Let us say there is an input_table:

+----------------------------------------------------+
|      obj1      obj2       obj3      fail_msg       |
+----------------------------------------------------+
|                                                    |
|        A                               msg1        |
|        A          B            C       msg2        |
|        A          B            D       msg3        |
+----------------------------------------------------+

i want to get the results as below from input table.

Results:

----------------------------------
          A         B            C      msg1, msg2
          A         B            D      msg1, msg3   

Similar to Listagg function , but group by with Null values.

Example:

select LISTAGG(fail_msg, ', ') WITHIN GROUP(ORDER BY fail_msg) failure_ message
    from input_table group by  obj1, obj2, obj3  

But this query is not merging null values in listagg()

can anyone please help me?

Thanks in advance.

That's very bad code but seem to do what you need:

with d as (
  select 'A' as o1, 'B' as o2, 'C' as o3, 'm1' as m from dual union all
  select 'A' as o1, 'B' as o2, 'D' as o3, 'm3' as m from dual union all
  select 'A' as o1, null as o2, null as o3, 'm2' as m from dual
)
select o1, o2, o3, listagg(m, ',') within group (order by o1)  from 
(select distinct nvl(d1.o1, d2.o1) as o1, nvl(d1.o2, d2.o2) as o2, nvl(d1.o3, d2.o3) as o3, d1.m
  from d d1 inner join d d2 on (nvl(d1.o1,d2.o1) = nvl(d2.o1, d1.o1) and nvl(d1.o2,d2.o2) = nvl(d2.o2, d1.o2) and nvl(d1.o3,d2.o3) = nvl(d2.o3, d1.o3)))
  group by o1, o2, o3;

GROUP BY alone won't yield this result no matter what you do, because it assigns each row to one and only one group. (There are ways to get summary rows, or multiple grouping sets in one query, but still those don't help here...)

The odds are you can do this more easily outside of SQL; but if you must do it in a query then you could try an approach like the following.

Note that this query is good enough for the example you gave; if your real requirements are more complicated, you may have to expand on these basic ideas. Also note that I'm showing the logic incrementally for clear explanation, but just the last query is what you'd want:

So first we can get a list of the messages with NULL values.

select *
  from input_table
 where obj2 is NULL
   and obj3 is NULL

We need to join this with the list of obj2 and obj3 values that exist for the given obj1 value; this is to create individual message records to apply in each group.

select null_list.obj1, obj_list.obj2, obj_list.obj3, null_list.fail_msg
  from            input_table null_list
       inner join (select distinct obj1, obj2, obj3
                     from input_table) as obj_list
               on null_list.obj1 = obj_list.obj1

Now combine that with the list of messages that didn't have null values

select null_list.obj1, obj_list.obj2, obj_list.obj3, null_list.fail_msg
  from            input_table null_list
       inner join (select distinct obj1, obj2, obj3
                     from input_table) as obj_list
               on null_list.obj1 = obj_list.obj1
UNION ALL
select *
  from input_table
 where obj2 is not null
   and obj3 is not null

(Note that the above only handles records where obj2 and obj3 either both are null, or neither are null. This is part of where I'm only addressing the example and you'd need to add more logic if you need to deal with different combinations of columns being null. That can get messy fast; like I said, SQL isn't really the tool for this job.)

Well now you have it as a list of messages applied to specific combinations of obj1,obj2,obj3 and a simple LILSTAGG should get you the rest of the way there.

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