2017-08-06 3 views
0

I ont un échantillon de données de http://sqlfiddle.com/#!4/ecba5/4:groupes de capture d'agrégats regex

with raw_data as(select 
'a{ thing_a<1234:1.1>>thing_b<->>thing_c<T>>thing_d<F>>thing_f<F>>thing_g<F>>thing_h<F>>thing_i<F>>thing_x<F>>thing_y<F>>thing_z<F>>#thing_a<234:1.2>>thing_b<->>thing_c<T>>thing_d<F>>thing_f<F>>thing_g<F>>thing_h<F>>thing_i<F>>thing_x<T>>thing_y<F>>thing_z<F>>#thing_a<345:1.3>>thing_b<->>thing_c<T>>thing_d<F>>thing_f<F>>thing_g<F>>thing_h<F>>thing_i<F>>thing_x<T>>thing_y<F>>thing_z<F>>#thing_a<456:1.4>>thing_b<->>thing_c<T>>thing_d<F>>thing_f<F>>thing_g<F>>thing_h<F>>thing_i<F>>thing_x<T>>thing_y<F>>thing_z<F>>#};ADD{some_thing<1234>>some_id<null>>some_stuff<2>>some_date<2013-07-09+02:00>>thing_zz<1>>foo_bar<0>>status_foo<0>>bar_value<0>>#some_thing<234>>some_id<null>>some_stuff<2>>some_date<2013-10-21+02:00>>thing_zz<1>>foo_bar<0>>status_foo<0>>bar_value<0>>#some_thing<345>>some_id<null>>some_stuff<2>>some_date<2013-07-22+02:00>>thing_zz<1>>foo_bar<0>>status_foo<0>>bar_value<0>>#some_thing<456>>some_id<null>>some_stuff<1>>some_date<2014-03-31+02:00>>thing_zz<1>>foo_bar<0>>status_foo<0>>bar_value<0>>#}]' value 
from dual) 
select 
regexp_count(value, 'thing_a<\d*:\d\.\d*>') thing_a, -- count all occurences of thing_a 
regexp_replace(value, 'thing_b<(-)>', '0'), -- How to only replace capturing group? 
--regexp_substr(regexp_replace(value, 'thing_b<(-)>', '0'),'thing_b<(.)>', 1, 1, NULL, 1), -- assuming this works - how to sum it up? there is no regexp_sum to aggregate the capturing groups? 
value 
from raw_data; 

Certaines agrégations sont faciles à savoir pour thing_a un regexp_count fonctionne très bien. Cependant pour tous les autres comme thing_b d'abord un remplacement de - à NaN et F à 0 et T à 1 devrait avoir lieu pour chaque groupe de capture. Ensuite, je veux résumer tout cela. Mais pas regexp_sum semble exister.

sortie souhaitée serait similaire à:

thing_a,thing_b,thing_d,...,thing_x 
4,0,0,...,3 

Répondre

1

Vous pouvez le faire en remplaçant tout le match avec une version reformaté qui élimine le groupe capturé:

regexp_replace(value, '(thing_b)<(-)>', '\1<0>') 

Et additionnant ces valeurs peut être fait avec SUM intégré Oracle():

sum(to_number(regexp_substr(regexp_replace(value, '(thing_b)<(-)>', '\1<0>'),'thing_b<(.)>', 1, 1, NULL, 1))) 

La requête complète:

with raw_data as(select 
    'a{ thing_a<1234:1.1>>thing_b<->>thing_c<T>>thing_d<F>>thing_f<F>>thing_g<F>>thing_h<F>>thing_i<F>>thing_x<F>>thing_y<F>>thing_z<F>>#thing_a<234:1.2>>thing_b<->>thing_c<T>>thing_d<F>>thing_f<F>>thing_g<F>>thing_h<F>>thing_i<F>>thing_x<T>>thing_y<F>>thing_z<F>>#thing_a<345:1.3>>thing_b<->>thing_c<T>>thing_d<F>>thing_f<F>>thing_g<F>>thing_h<F>>thing_i<F>>thing_x<T>>thing_y<F>>thing_z<F>>#thing_a<456:1.4>>thing_b<->>thing_c<T>>thing_d<F>>thing_f<F>>thing_g<F>>thing_h<F>>thing_i<F>>thing_x<T>>thing_y<F>>thing_z<F>>#};ADD{some_thing<1234>>some_id<null>>some_stuff<2>>some_date<2013-07-09+02:00>>thing_zz<1>>foo_bar<0>>status_foo<0>>bar_value<0>>#some_thing<234>>some_id<null>>some_stuff<2>>some_date<2013-10-21+02:00>>thing_zz<1>>foo_bar<0>>status_foo<0>>bar_value<0>>#some_thing<345>>some_id<null>>some_stuff<2>>some_date<2013-07-22+02:00>>thing_zz<1>>foo_bar<0>>status_foo<0>>bar_value<0>>#some_thing<456>>some_id<null>>some_stuff<1>>some_date<2014-03-31+02:00>>thing_zz<1>>foo_bar<0>>status_foo<0>>bar_value<0>>#}]' value 
    from dual) 
select 
regexp_count(value, 'thing_a<\d*:\d\.\d*>') thing_a, -- count all occurences of thing_a 
regexp_replace(value, '(thing_b)<(-)>', '\1<0>'), -- How to only replace capturing group? 
sum(to_number(regexp_substr(regexp_replace(value, '(thing_b)<(-)>', '\1<0>'),'thing_b<(.)>', 1, 1, NULL, 1))) -- assuming this works - how to sum it up? there is no regexp_sum to aggregate the capturing groups? 
from raw_data;