Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic Limit in PostgreSQL

Tags:

postgresql

I have function returning list of Employees, My requirement is if i pass Limit to function than i should get result with limit and offset, If i don't pass limit than all the rows should be returned

for example

When Limit is greater than 0(I am passing Limit as 10)
Select * from Employees
Limit 10 offset 0

When Limit is equal to 0 than
Select * from Employees

Is their any way to do such logic in function?

like image 766
manthan davda Avatar asked Sep 15 '15 08:09

manthan davda


People also ask

How do I limit values in PostgreSQL?

The PostgreSQL LIMIT clause is used to get a subset of rows generated by a query. It is an optional clause of the SELECT statement. The LIMIT clause can be used with the OFFSET clause to skip a specific number of rows before returning the query for the LIMIT clause.

Does PostgreSQL have limit?

PostgreSQL LIMIT is an optional clause of the SELECT statement that constrains the number of rows returned by the query. The statement returns row_count rows generated by the query. If row_count is zero, the query returns an empty set.

What is offset and limit in PostgreSQL?

LIMIT will retrieve only the number of records specified after the LIMIT keyword, unless the query itself returns fewer records than the number specified by LIMIT. OFFSET is used to skip the number of records from the results.

What is limit and offset in SQL?

The limit option allows you to limit the number of rows returned from a query, while offset allows you to omit a specified number of rows before the beginning of the result set. Using both limit and offset skips both rows as well as limit the rows returned.


2 Answers

Yes, you can pass an expression for the LIMIT and OFFSET clauses, which includes using a parameter passed in to a function.

CREATE FUNCTION employees_limited(limit integer) RETURNS SET OF employees AS $$
BEGIN
  IF limit = 0 THEN
    RETURN QUERY SELECT * FROM employees;
  ELSE
    RETURN QUERY SELECT * FROM employees LIMIT (limit)
  END IF;
  RETURN;
END; $$ LANGUAGE plpgsql STRICT;

Note the parentheses around the LIMIT clause. You can similarly pass in an OFFSET value.

This example is very trivial, though. You could achieve the same effect by doing the LIMIT outside of the function:

SELECT * FROM my_function() LIMIT 10;

Doing this inside of a function would really only be useful for a complex query, potentially involving a large amount of data.

Also note that a LIMIT clause without an ORDER BY produces unpredictable results.

like image 117
Patrick Avatar answered Sep 25 '22 06:09

Patrick


Sorry I can't comment. Solution is almost provided by Patrick.
First we should write function to return result without limitation.

CREATE FUNCTION test () 
RETURNS TABLE (val1 varchar, val2 integer) AS $$
    BEGIN
    RETURN QUERY SELECT val1, val2 FROM test_table;
    END;
$$ LANGUAGE plpgsql;

Then we have to write wrapper function, which will process limitation.

CREATE FUNCTION test_wrapper (l integer DEFAULT 0)
RETURNS TABLE (name varchar, id integer) AS $$
    BEGIN
        IF l = 0 THEN
            RETURN QUERY SELECT * FROM test(); -- returns everything
        ELSE
            RETURN QUERY SELECT * FROM test() LIMIT (l); -- returns accordingly
        END IF;
    END;
$$ LANGUAGE plpgsql;

In my case I needed to return tables as final result, but one can get anything required as return from wrapper function.

like image 41
Dmitry Avatar answered Sep 24 '22 06:09

Dmitry