Как я могу параметризовать этот массив jsonb содержит запрос? - PullRequest
0 голосов
/ 18 февраля 2020

У меня есть следующее sql:

WITH
ni AS (SELECT DISTINCT ON(issuercik) issuercik FROM new_insiders
WHERE date_filed > (CURRENT_DATE - INTERVAL '360 day')::date AND ( tickers @> '["MSFT"]'::jsonb ) ORDER BY issuercik, date_filed DESC),
t AS (SELECT cik FROM companies WHERE data->'tickers' @> '["MSFT"]'::jsonb ) 
SELECT ni.issuercik AS first, t.cik AS second FROM ni FULL OUTER JOIN t ON ni.issuercik = t.cik;

Что дает мне (как и ожидалось):

789019 | 789019

Теперь мне нужно параметризовать запрос, но я не могу:

DEALLOCATE stmt;
PREPARE stmt AS WITH
ni AS (SELECT DISTINCT ON(issuercik) issuercik FROM new_insiders
WHERE date_filed > (CURRENT_DATE - INTERVAL '360 day')::date AND ( tickers @> '["$1"]'::jsonb ) ORDER BY issuercik, date_filed DESC),
t AS (SELECT cik FROM companies WHERE data->'tickers' @> '["$1"]'::jsonb ) 
SELECT ni.issuercik AS first, t.cik AS second FROM ni FULL OUTER JOIN t ON ni.issuercik = t.cik;

EXECUTE stmt('MSFT');

Я получил пустую строку, и это потому, что он буквально ищет "$1". Я пытаюсь удалить двойные кавычки, затем он жалуется

ERROR:  invalid input syntax for type json
LINE 4: ...DATE - INTERVAL '360 day')::date AND ( tickers @> '[$1]'::js...
                                                             ^
DETAIL:  Token "$" is invalid.

Я не уверен, как решить эту.

1 Ответ

1 голос
/ 18 февраля 2020

Если вы просто хотите проверить, содержит ли массив заданное значение, вы можете использовать ? вместо @>.

Это будет выглядеть так:

DEALLOCATE stmt;

PREPARE stmt AS
WITH
    ni AS (
        SELECT DISTINCT ON(issuercik) issuercik 
        FROM new_insiders
        WHERE 
            date_filed > (CURRENT_DATE - INTERVAL '360 day')::date 
            AND tickers ? $1
        ORDER BY issuercik, date_filed DESC
    ),
    t AS (
        SELECT cik 
        FROM companies 
        WHERE data->'tickers' ? $1
    ) 
SELECT ni.issuercik AS first, t.cik AS second 
FROM ni 
FULL OUTER JOIN t ON ni.issuercik = t.cik;

EXECUTE stmt('MSFT');
...