Преобразование моего расчета в пользовательскую функцию - PullRequest
0 голосов
/ 02 июля 2019

Я пытаюсь преобразовать мои вычисления в UDF, но я продолжаю получать ошибки и не уверен, как их исправить.

Вот код:

CREATE FUNCTION f_q1 (integer) RETURNS integer stable as $$
SELECT COUNT(DISTINCT(CASE WHEN q_1 IN ('8', '9', '10') THEN RESPONSE_ID END))*1.0 / COUNT(DISTINCT(CASE WHEN q_1 IS NOT NULL THEN RESPONSE_ID END))*1.0
$$ language sql;

I 'По сути, я пытаюсь взять приведенный ниже код:

SELECT
COUNT(DISTINCT(CASE WHEN f.q_1 IN ('8', '9', '10') THEN f.RESPONSE_ID END))*1.0 / COUNT(DISTINCT(CASE WHEN f.q_1 IS NOT NULL THEN f.RESPONSE_ID END))*1.0 AS q_1
FROM FACT f

и создать его в UDF, к которому я могу обращаться по всему запросу.

Я впервые делаю UDF - может кто-нибудь помочьмне исправить это?

Ответы [ 2 ]

0 голосов
/ 02 июля 2019

В настоящее время пользовательские функции Amazon Redshift являются только скалярными. Они принимают в качестве входных параметров только одно значение и возвращают одно выходное значение. https://docs.aws.amazon.com/redshift/latest/dg/udf-creating-a-scalar-sql-udf.html

Если вы хотите инкапсулировать агрегацию, например COUNT(DISTINCT ), вам нужно будет использовать хранимую процедуру. https://docs.aws.amazon.com/redshift/latest/dg/stored-procedure-overview.html

В качестве альтернативы вы можете выполнить COUNT(DISTINCT ) отдельно и инкапсулировать логику CASE в двух UDF. Например:

--Two parameters: q_1 and response_id
CREATE FUNCTION f_key_question(INTEGER,INTEGER) 
RETURNS INTEGER
STABLE AS $$
    SELECT CASE WHEN $1 IN (8,9,10) THEN $2 ELSE NULL END
$$ LANGUAGE SQL
;
CREATE FUNCTION f_any_question(INTEGER) 
RETURNS INTEGER
STABLE AS $$
    SELECT CASE WHEN $1 IS NOT NULL THEN $2 ELSE NULL END
$$ LANGUAGE SQL
;
SELECT COUNT(DISTINCT(f_key_question(f.q_1,f.response_id))::NUMERIC
     / COUNT(DISTINCT(f_any_question(f.q_1,f.response_id))::NUMERIC  AS q_1
FROM fact f
;
0 голосов
/ 02 июля 2019

CREATE FUNCTION f_q1 (integer) говорит, что вы передаете одно целое число.Следовательно, ваша UDF может использовать это целое число только для определения своего вывода.

В функции нет ничего под названием q_1, и при этом не существует нескольких строк ввода.Это скалярный UDF , что означает, что он принимает определенное количество входных значений и возвращает одно выходное значение.

Вы могли бы вместо этого использовать Хранимая процедура скалярного UDF.

Но, честно говоря, если ваш вышеуказанный запрос работает, просто продолжайте его использовать.Нет особого преимущества в том, чтобы помещать его в функцию.

...