#sql #amazon-web-services #amazon-redshift
#sql #amazon-веб-сервисы #amazon-redshift
Вопрос:
Я пытаюсь написать простой запрос с предложением in следующим образом:
SELECT *
FROM storeupcsalesbyday
WHERE date >= '9/1/2020' AND date <= '9/10/2020' AND upc in ('0000000004011', '0000000094011')
Мне нужно иметь возможность передавать значения в предложении in в качестве параметра, количество значений в предложении in является переменным и может составлять один или тысячи в зависимости от пользовательского ввода. В других базах данных sql я решил эту проблему, создав пользовательскую функцию, которая принимает строку, разбивает ее на разделитель и вставляет значения во временную таблицу, затем я бы выбрал все из временной таблицы для использования в моем предложении in. Однако пользовательские функции в redshift не допускают использование таблиц в качестве возвращаемого типа. Как другие решают эту проблему в redshift.
Спасибо
Комментарии:
1. Вы рассматривали возможность создания хранимых процедур в Amazon Redshift вместо определяемой пользователем функции? Он обладает большей гибкостью (особенно версия Python).
2. @JohnRotenstein Похоже, что redshift разрешает python только для UDFS, а не для хранимых процедур. Однако я изучаю хранимые процедуры для решения этой проблемы.
3. О! Вы правы. Он используется только
plpgsql
для хранимых процедур.
Ответ №1:
Я смог создать хранимую процедуру, которая принимает varchar и создает временную таблицу всех «фрагментов» varchar, разделенных разделителем (в данном случае ‘,’). Я просто хотел поделиться этим здесь на случай, если у кого-то еще возникнет эта проблема.
Вот процедура:
CREATE OR REPLACE Procedure sp_UPCStringToTempTable(upcList IN varchar(max))
AS 'DECLARE
idx int;
slice varchar(8000);
upcListVar varchar(max);
BEGIN
idx = 1;
upcListVar = upcList;
DROP TABLE if exists tmp_upc;
CREATE TEMP TABLE tmp_upc(upc varchar(14));
WHILE idx != 0 LOOP
idx = charindex('','', upcListVar);
IF idx != 0 THEN
slice = left(upcListVar, idx - 1);
END IF;
IF idx = 0 THEN
slice = upcListVar;
END IF;
IF len(slice) > 0 THEN
INSERT INTO tmp_upc values (slice);
END IF;
upcListVar = right(upcListVar, len(upcListVar) - idx);
END LOOP;
END;
' LANGUAGE plpgsql;
Ответ №2:
create table num(id int) ;
insert into num values(1), (2),(3);
with t as
(
select split_part('0000000004011, 0000000094011',',',id ) col1 from num
)
select * from a join t on a.col1 = t.col1
Это должно решить вашу проблему.
Комментарии:
1. Мне трудно реализовать это, на что должна ссылаться таблица a?