PostgreSQL function returning a data cube

混江龙づ霸主 提交于 2021-02-10 06:31:28

问题


First off, the iceberg-cube query is defined as in

Let's say I have a relation item,location,year,supplier,unit_sales, and I would like to write a plpgsql functions as a wrapper around the query in the image, to specify the parameter N, like so:

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'

What do I need to add to Code here-part, to make this work? How to specify a data cube as a return type in plpgsql?


回答1:


To make your plpgsql function work, you need a RETURNS clause matching what you return. And you need to actually return something. I suppose:

CREATE OR REPLACE FUNCTION iceberg_query ( percentage numeric) 
  RETURNS TABLE (item ?TYPE?, location ?TYPE?, year ?TYPE?, ct bigint)
AS
$func$
DECLARE
    numrows bigint := (SELECT count(*) FROM sales);
BEGIN
   RETURN QUERY
   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;

Replace the placeholders ?TYPE? with actual (undisclosed) data types.

Call the function with:

SELECT * FROM iceberg_query (10);

Note how I table-qualify all column names in the query to avoid naming collisions with the new OUT parameters of the same name.

And note the use of numeric instead of integer as pointed out by Scoots in a comment.

Related:

  • How to return result of a SELECT inside a function in PostgreSQL?
  • plpgsql error "RETURN NEXT cannot have a parameter in function with OUT parameters" in table-returning function

Aside: you don't need a function for this. This plain SQL query does the same:

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

Provide a numeric literal (10.0, not 10) to avoid integer division and the rounding that comes with it.



来源:https://stackoverflow.com/questions/55240052/postgresql-function-returning-a-data-cube

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!