Функция PostgreSQL, возвращающая куб данных - PullRequest
2 голосов
/ 19 марта 2019

Во-первых, запрос куба айсберга определяется как enter image description here

Допустим, у меня есть отношение item,location,year,supplier,unit_sales, и я хотел бы написать plpgsql функции как обертка вокруг запроса в изображении, для указания параметра N, вот так:

create or replace function iceberg_query( percentage integer ) 
returns cube
/* Code here */
as
$$
declare
    numrows int;
begin
    select count(*) into numrows from sales;
    select item, location, year, count(*) 
        from sales  
    group by cube(item,location,year)   
    having count(*) >= numrows*percentage/100;
end;
$$ language 'plpgsql'

Что мне нужно добавить к Code here -part, чтобы это работало? Как указать куб данных в качестве типа возврата в plpgsql?

1 Ответ

1 голос
/ 19 марта 2019

Чтобы ваша функция plpgsql работала, вам нужно предложение RETURNS, совпадающее с тем, что вы возвращаете. И вам нужно на самом деле вернуть что-то. Я полагаю:

CREATE OR REPLACE FUNCTION iceberg_query ( percentage numeric) 
  <b>RETURNS TABLE (item ?TYPE?, location ?TYPE?, year ?TYPE?, ct bigint)</b>
AS
$func$
DECLARE
    numrows bigint := (SELECT count(*) FROM sales);
BEGIN
   <b>RETURN QUERY</b>
   SELECT s.item, s.location, s.year, count(*) 
   FROM   sales s
   GROUP  BY cube(s.item,s.location,s.year)   
   HAVING count(*) >= numrows * percentage / 100;
END
$func$  LANGUAGE plpgsql;

Заменить заполнители ?TYPE? на фактические (нераскрытые) типы данных.

Вызовите функцию с помощью:

SELECT * FROM iceberg_query (10);

Обратите внимание, как я квалифицирую в таблице все имена столбцов в запросе, чтобы избежать конфликтов имен с новыми параметрами OUT с тем же именем.

И обратите внимание на использование numeric вместо integer, как указано Скотсом в комментарии .

Связанный:

В сторону: вам не нужно функция для этого. Этот простой SQL-запрос делает то же самое:

SELECT s.item, s.location, s.year, count(*)
FROM   sales s
GROUP  BY cube(s.item,s.location,s.year)
HAVING count(*) >= (SELECT count(*) * $percentage / 100 FROM sales);  -- your pct here

Укажите числовой литерал (10.0, а не 10), чтобы избежать целочисленного деления и округления, которое идет с ним.

...