Как использовать группу, но при этом умно обращаться к каждому числовому значению - PullRequest
0 голосов
/ 11 октября 2019

Мне нужно «сгруппировать» мои данные, чтобы различать тесты (каждый тест имеет определенный идентификатор, имя и температуру) и рассчитывать их количество, стандартное отклонение и т. Д. Но мне также нужен доступ к каждому значению необработанных данных из каждогогруппа, для дальнейших вычислений индексов, которые я делаю в скрипте Python.

Я нашел два решения этой проблемы, но оба кажутся неоптимальными / ошибочными:

1) Использование listagg для хранения каждого необработанного значения, которое было сгруппировано в одну строку строки. Он работает, но не оптимизирован: я объединяю несколько значений с плавающей запятой в гигантскую строку, которую я немедленно деккатенирую и преобразовываю обратно в число с плавающей запятой. Это кажется необходимым и дорогостоящим.

2) Полностью удалить группу и выполнить подсчет и стандартное отклонение, хотя разбиение . Но это кажется мне еще хуже. Я не знаю, оптимизирует ли это PLSQL / oracle, это может быть вычисление одинакового количества и стандартного отклонения для каждой строки (я не знаю, как это проверить). Результат запроса также становится грязным: поскольку больше нет «group by», мне нужно добавить несколько проверок в мой файл python, чтобы дифференцировать данные каждого теста (конкретный идентификатор, имя и температура).

Я думаю, что моё первое решение можно улучшить, но я не знаю как. Как я могу использовать группу, но все равно получить доступ к каждому числовому значению умно ?

Функция, похожая на list_agg, но с выходным типом коллекции / массива вместо строкового типа выходного сигнала, возможно, может сработать (своего рода «массив_агг», совместимый с оракулом), но я не знаю ни одной.

РЕДАКТИРОВАТЬ: выборочные данные являются сложными и, вероятно, ограничены просмотром компании, но я могу показать вам мой упрощенный запрос для моего 1):

SELECT 
    rav.rav_testid as test_id, 
    tte.tte_testname as test_name,
    tsc.tsc_temperature as temperature,
    listagg(rav.rav_value, ' ')WITHIN GROUP (ORDER BY rav.rav_value) as all_specific_test_values,
    COUNT(rav.rav_value) as n, 
    STDDEV(rav.rav_value) as sigma,

FROM
    ...
    (8 inner joins)


GROUP BY
    rav.rqv_testid, tte.tte_testname,tsc.tsc_temperature

ORDER BY
    rav.RAV_testid, tte.tte_testname, spd.SPD_SPLITNAMEINTERNAL,tsc.tsc_temperature

Результат выглядит следующим образом:

test_id | test_name  | temperature | all_specific_test_values | n | sigma
-------------------------------------------------------------------------
6001    |VADC_A(...) | -40         | ,8094034194946289 ,8(...)| 58 | 0,54
6001    |VADC_A(...) |  25         | ,5054857852946545 ,6(...)| 56 | 0,24
6001    |VADC_A(...) |  150        | ,8625754277452524 ,4(...)| 56 | 0,26
6002    |VADC_B(...) | -40         | ,9874514651548454 ,5(...)| 57 | 0,44

Ответы [ 2 ]

1 голос
/ 11 октября 2019

Я бы предложил воспользоваться решением @ Gordon_Linoff. Это, вероятно, самое стандартное решение.

Если вы хотите использовать менее стандартное решение, вы можете иметь group by, который возвращает коллекцию в качестве одного из столбцов. Предположительно, ваш сценарий может перебирать эту коллекцию, хотя для этого может потребоваться немного работы в сценарии.

create type num_tbl as table of number;
/

create table foo (
  grp integer,
  val number
);

insert into foo values( 1, 1.1 );
insert into foo values( 2, 1.2 );
insert into foo values( 1, 1.3 );
insert into foo values( 2, 1.4 );

select grp, avg(val), cast( collect( val ) as num_tbl )
  from foo
 group by grp
1 голос
/ 11 октября 2019

Я думаю, вам нужны аналитические функции:

select t.*,
       count(*) over (partition by test) as cnt,
       avg(value) over (partition by test) as avg_value,
       stddev(value) over (partition by test) as stddev_value
from t;

Это добавляет дополнительные столбцы в каждой строке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...