问题
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