Как я могу передать список, массив или строку для разделения в качестве параметра в redshift

#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?