Как исправить синтаксис моей функции postgres в соответствии с пользовательским параметром

#sql #postgresql #where-clause #greatest-n-per-group #sql-function

#sql #postgresql #where-предложение #наибольшее число пользователей на группу #sql-функция

Вопрос:

Я пытаюсь создать функцию postgreql, я немного запутался в том, какой формат синтаксиса использовать, когда я передаю оператор select, который принимает параметр (этот параметр может быть строкой или списком строк)

Вот исходный запрос select, который я использовал ранее, с placeholders моим параметром. Этот выбор отлично подходит для меня!

 SELECT DISTINCT ON (symbol) symbol,
                next_dividend_date, ex_dividend_date
           FROM api.security_stats 
           WHERE api.security_stats.symbol 
           IN ({placeholders}) 
           ORDER BY symbol, date desc;
   
 

Проблема в том, что я попытался преобразовать приведенное выше в полезную функцию, где пользователи могут вводить параметр для функции. Однако я не могу заставить синтаксис работать. Кроме того, в документации psql для функций есть много примеров синтаксиса. Я не уверен, какой из них использовать для моего случая?

 CREATE FUNCTION dividend(stocks char)
RETURNS TABLE(symbol char, next_dividend_date date, ex_dividend_date date) AS $
    SELECT DISTINCT ON (symbol) symbol, next_dividend_date, ex_dividend_date
                                                FROM api.security_stats 
                                                WHERE api.security_stats.symbol 
                                                IN ({stocks}) ORDER BY symbol, date desc) 
                                                $ LANGUAGE SQL;
 

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

Спасибо за любую помощь!

Ответ №1:

Я думаю, вы хотите что-то вроде:

 create function dividend(p_stocks char)
    returns table(symbol char, next_dividend_date date, ex_dividend_date date) 
as $
    select distinct on (symbol) symbol, next_dividend_date, ex_dividend_date
    from api.security_stats 
    where api.security_stats.symbol = any(string_to_array($1, ','))
    order by symbol, date desc 
$ language sql;
 

Это функция SQL, возвращающая таблицу; вы можете ссылаться на входной аргумент с позиционной нотацией $1 .

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

Или, если вы хотите передать свой ввод в виде массива:

 create function dividend(p_stocks text[])
    returns table(symbol char, next_dividend_date date, ex_dividend_date date) 
as $
    select distinct on (symbol) symbol, next_dividend_date, ex_dividend_date
    from api.security_stats 
    where api.security_stats.symbol = any($1)
    order by symbol, date desc 
$ language sql;
 

Комментарии:

1. Большое вам спасибо за то, что все разъяснили. Глядя на этот фрагмент, теперь я понимаю параметры функции для postgres. Я еще не тестировал его, но скоро прокомментирую и дам вам знать!

2. Я могу заставить этот запрос работать! большое вам спасибо, однако у меня есть вопрос: допускает ли этот метод только одну строку в параметре? Что делать, если у меня есть список строк. Например, select dividend('MSFT'); это отлично работает! Но когда я пытаюсь сделать, select dividend('MSFT', 'AAPL'); Функция, похоже, не работает, я должен структурировать ввод по-другому?

3. @Dre: функция принимает строку CSV, так что это будет: select dividend('MSFT,AAPL') . Или вы можете изменить код функции, чтобы принимать непосредственно массив, и вызвать его следующим образом: select divident(array['MSFT', 'AAPL'])

4. Ради любопытства, как будет выглядеть другая функция, которая напрямую принимает массив? Я думаю, что было бы лучшим вариантом для моего конкретного варианта использования. Если я использую этот запрос как часть веб-приложения, я думаю, формат массива может быть лучше? Меньше преобразования данных.

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