select * from
(SELECT ID,purchase_list,
CASE WHEN purchase_list LIKE '12432%' THEN replace(purchase_list,12432,'Amt_Saved: Mastercard(12432)')
END AS purchase_amt
FROM (
SELECT ID,index,d.value::string AS purchase_list
FROM (
SELECT ID,c.value::string AS purchase_list
FROM table_1,LATERAL flatten(INPUT=>split(purchase_order_list, '|')) c
), LATERAL flatten(INPUT=>split(purchase_list, ';')) d
)
)WHERE purchase_amt is not null
Когда я запускаю вышеуказанный запрос, я получаю результаты, как указано ниже:
ID PURCHASE_LIST PURCHASE_AMT
12810789 12432=3.00 Savings1: Mastercard(12432)=3.00
12810789 12432=0.99 Savings1: Mastercard(12432)=0.99
12810789 12432=0.49 Savings1: Mastercard(12432)=0.49
Я хочу суммировать эти суммы (3,00 + 0,99 + 0,49) = 4,48 и отобразить этот результат в том же или другом столбце.
Результат должен выглядеть так:
ID PURCHASE_LIST PURCHASE_AMT
12810789 12432=4.48 4.48
Как реализовать это с помощью функции SUM, используя любую другую логику?
Пожалуйста, руководство. Заранее спасибо :)
Во-первых, ваш существующий SQL можно переписать так:
SELECT
a.id,
d.value::string AS purchase_list,
IFF( purchase_list LIKE '12432%', REPLACE(purchase_list, 12432, 'Amt_Saved: Mastercard(12432)'), null) purchase_amt
FROM table_1 AS a
,LATERAL flatten(INPUT=>split(a.purchase_order_list, '|')) c
,LATERAL flatten(INPUT=>split(c.value::string, ';')) d
WHERE purchase_amt IS NOT NULL;
Итак, мы можем добавить предложение SUM() OVER(), чтобы получить итог по строке, если вам нужны части и итог:
SELECT
a.id,
d.value::string AS purchase_list,
IFF( purchase_list LIKE '12432%', REPLACE(purchase_list, 12432, 'Amt_Saved: Mastercard(12432)'), null) purchase_amt,
SUM(REGEXP_REPLACE(purchase_list, '12432=([0-9.]+)', '\\1', 1,1,'e')::number(9,3)) over (partition by id) as sum_total
FROM table_1 AS a
,LATERAL flatten(INPUT=>split(a.purchase_order_list, '|')) c
,LATERAL flatten(INPUT=>split(c.value::string, ';')) d
WHERE purchase_amt IS NOT NULL;
Я БЫ | ПОКУПКА_СПИСОК | ПОКУПКА_AMT | ИТОГО |
---|---|---|---|
12810789 | 12432=3,00 | Amt_Saved: Mastercard(12432)=3.00 | 4,48 |
12810789 | 12432=0,99 | Amt_Saved: Mastercard(12432)=0,99 | 4,48 |
12810789 | 12432=0,49 | Amt_Saved: Mastercard(12432)=0,49 | 4,48 |
ИЛИ вы можете сгруппировать и не заботиться обо всех подзначениях:
SELECT
a.id,
SUM(REGEXP_REPLACE(d.value::string, '12432=([0-9.]+)', '\\1', 1,1,'e')::number(9,3)) AS sum_total
FROM table_1 AS a
,LATERAL flatten(INPUT=>split(a.purchase_order_list, '|')) c
,LATERAL flatten(INPUT=>split(c.value::string, ';')) d
GROUP BY 1;
дает:
Я БЫ | ИТОГО |
---|---|
12810789 | 4,48 |
правильно, когда я использовал ::number(9,3)
, я не объяснил, что я делаю, так что это моя ошибка, то есть определение числа с фиксированной точкой, которое может содержать только 9 цифр после запятой и три после запятой. Если у вас есть большее число или требуется большая точность, вам нужно будет использовать значение, которое допустимо для ваших данных. Вы можете использовать FLOAT/DOUBLE (они одинаковы), но числа с плавающей запятой не подходят для работы с деньгами. И учитывая упомянутые вами "названия и номера кредитных карт", я одолжил их в сейфе.
Я получаю эти ошибки: числовое значение не распознано и числовое значение вне допустимого диапазона. Можно ли отсортировать это с помощью TRY_CAST или TRY_TO_NUMBER?