SQL - wyciąganie samych cyfr z kolumny. Problem z sumowaniem

0

Cześć,

Mam taką querkę:

SELECT SUM(regexp_replace(root_cause, '[^[:digit:]]', '')) AS_Number
FROM booker.o_remedy
WHERE
item = 'EU - Writing Requests'
AND extract(week from (date(resolved_date))) = 27
AND extract(year from (date(create_date))) = 2021
AND root_cause Like '%SC%'
)

Wyciąga ona same cyfry z danej kolumny(kkolumny: root_cause). Np. mam wiersz z tej kolumny, w którym są dane: 31 SC, to querka wyciąga z niego cyfrę 31, po czym sumuje wszystkie cyfry z danej kolumny (kolumny: root_cause).
Mam jeden problem. Mając w danej komórce dane np: 31 SC to wszystko jest ok - querka wyciąga cyfrę 31 i jest ona później sumowana z innymi komórkami z danej kolumny. Natomiast mając 3 SC 1 SC, to wyciąga mi cyfry 3 oraz 1 i querka sumując dane z kolumny widzi cyfrę z tego wiersza jako 31, a chciałbym żeby sumowała cyfry oddzielnie, czyli oddzielnie 3 oraz oddzielnie 1. Bardzo proszę o pomoc/wskazówkę co musiałbym dodać do querki/jak ją zmodyfikować, aby w przypadku zapisu np: 31 SC querka wyciągała i sumowała z innymi kolumnami cyfrę 31, a np w przypadku zapisu 3 SC 1 SC dodawała oddzielnie 3 oraz 1, a nie widziała jej jako 31.

Ogromne dzięki!

1

Wnioskuję, że chodzi o oracle. W takim wypadku obawiam się, ze samym SQL'em będzie ciężko. Musiałbyś napisać odpowiednią funkcję, która daną krotkę przepuści przez funkcję, która zwróci Ci typ tabelaryczny tak abyś miał albo 42 albo 4 i 2, a następnie ten typ tabelaryczny zsumuje jako jedną wartość, którą podstawisz sobie do zapytania.
Przykład poniżej:
https://livesql.oracle.com/apex/livesql/file/content_EWQDO1QCRPAL8WOKWNWBXWKM0.html

2
  1. 31 SC, to querka wyciąga z niego cyfrę 31 - 31 wygląda na liczbę, a nie na cyferkę.
  2. Możesz z wartości zrobić CSV:
with 
sample_input as (
  select 'xx31 abc 23,def,3334.3 4 foo bar 1' root_cause from dual
)
select 
    s.root_cause,
    regexp_replace(
      regexp_replace(s.root_cause,'[^[:digit:]]+',','),
      '^,|,$',''
    ) csv_values
from sample_input s;
  1. W necie jest masa przykładów jak CSV zamienić na wiersze -> google: split string into rows oracle

Nie trzeba funkcji, można spokojnie ogarnąć sqlem.

0

@yarel: Czyli to bedzie wyglądało tak:
Bo cos mi nie trybi..

with 
sample_input as (
  select 'xx31 abc 23,def,3334.3 4 foo bar 1' root_cause from dual
)
select 
    s.root_cause,
 regexp_replace(
      regexp_replace(s.root_cause,'[^[:digit:]]+',','),
      '^,|,$',''
    ) csv_values
from sample_input s, booker.o_remedy
WHERE
item = 'EU - Writing Requests'
AND extract(week from (date(resolved_date))) = 27
  AND extract(year from (date(create_date))) = 2021
 AND root_cause Like '%SC%'
)
0

Po co usuwasz niepasujące znaki przez regexp_replace, kiedy możesz po prostu wyciągnąć znaki pasujące? Nie rozumiem też po co na siłę robić tutaj dodatkową tabelę, ale może to wynika z mojego braku wiedzy na temat Oracle.
Moim zdaniem wystarczy w części select tylko to:

select sum(regexp_substr(root_cause, '^\d+')) as Number

Przykład: http://sqlfiddle.com/#!4/711db/4/0

BTW zapytania z like, gdzie % figuruje gdziekolwiek poza końcem, są powolne, a te, w których jest na początku, będą ekstremalnie wolne - silnik bazy danych będzie musiał przeskanować KAŻDY (pasujący do poprzednich warunków) rekord tabeli. Ale sądząc po tym, że likea dałeś na końcu listy warunków świadczy, że to rozumiesz, plus dla Ciebie :-)

2

@lukzar: Nie, nie będzie tak wyglądało. Ten kod zapytania, który podałem, zamienia "123 SC 456 xy 1" -> "123,456,1". Punkt 3) dotyczy tego, że taką wartość CSV "123,456,1" można zamienić na wiersze:

123
456
1

Zamiana CSV na wiersze, podałem Ci pod jakim hasłem szukać.

Logicznie więc problem można rozbić na 3 mniejsze:

  1. Zamiana wartości na CSV
  2. Rozbicie CSV na wiersze
  3. Sumowanie
0

@ŁF: Dzięki za podpowiedź :) jednak po użyciu Twojego selecta: select sum(regexp_substr(root_cause, '^\d+')) as Number, wartości w kolumnie są puste

0

@yarel:

Dziękuję. Tutaj wszystko (prawie) ładnie mi działa. Tzn. mam kolumnę numbers, gdzie mam odseparowane cyfry w danej komórce po przecinku. Tylko jak robie sumę to przecinek jest elementem, który przeszkadza w sumowaniu. I teraz nie mam zielonego pojęcia jak i jaką dodać funkcję, żeby zamiast przecinka była następna kolumna. Czyli jak z poniższej querki mam w danej komórce, która wygląda: 5 SC 4 sc ,wynik 5,4: to aby 5 była w jednej kolumnie, a 4 w kolejnej, zamiast tego przecinka. Albo, żeby dało się to policzyć w jednej kolumnie typu 5+4.Bo kombinuje tu z różnymi poradnikami z neta i jestem w kompletnej kropce...

select 
    root_cause,
    regexp_replace(
      regexp_replace(root_cause,'[^[:digit:]]+',','),
      '^,|,$','' Numbers
    )
FROM booker.o_remedy
WHERE
item = 'EU - Writing Requests'
AND extract(week from (date(resolved_date))) = 28
AND extract(year from (date(create_date))) = 2021
AND root_cause_details ILike '%SC%'
1

@lukzar: Łap kolejny przykład.

WITH 
sample_data AS ( 
    SELECT 'Case1' txt, '3,5,7' csv FROM dual
    UNION ALL
    SELECT 'Case2' txt, '2,4,6,8,10' FROM dual
    UNION ALL
    SELECT 'Case3' txt, '1' FROM dual
),
sample_data_with_count as (
   select d.*,regexp_count(csv,'[^,]+')+1 numbers_cnt from sample_data d 
),
split_data as (
  select distinct level lvl,s.*,regexp_substr(csv,'[^,]+',1,level) zz from sample_data_with_count s connect by level<=s.numbers_cnt 
)
select sd.* from split_data sd where sd.zz is not null order by sd.txt,sd.csv,sd.lvl,sd.zz
;

To jedna z możliwości obrazująca, że da się w sqlu. google -> "split string to rows oracle".

1 użytkowników online, w tym zalogowanych: 0, gości: 1