Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在postgresql中限制多返回查询的结果集_Sql_Postgresql_Sql Limit_Set Returning Functions - Fatal编程技术网

如何在postgresql中限制多返回查询的结果集

如何在postgresql中限制多返回查询的结果集,sql,postgresql,sql-limit,set-returning-functions,Sql,Postgresql,Sql Limit,Set Returning Functions,我有多个返回查询语句的函数。最后,我只想得到N条随机记录。如果我在最后为每个返回查询语句设置了limitmax_size,我将得到返回查询时间的max_size*计数 我的函数的简短版本: CREATE OR REPLACE FUNCTION android_getproposedsongs_test( IN puserid character varying, max_size int) RETURNS

我有多个返回查询语句的函数。最后,我只想得到N条随机记录。如果我在最后为每个返回查询语句设置了limitmax_size,我将得到返回查询时间的max_size*计数

我的函数的简短版本:

CREATE OR REPLACE FUNCTION android_getproposedsongs_test(
                                          IN puserid character varying, max_size int)
    RETURNS TABLE(sid uuid, method text) AS
$BODY$
DECLARE
    songCount int;
BEGIN

RETURN QUERY 
    SELECT trackid as sid, lower('popular') as method
    FROM ratingrecord
    WHERE trackid NOT IN (
       SELECT trackid FROM ratingrecord WHERE userid = puserid)
    AND ratingrecord.rating > 0
    GROUP BY trackid
    HAVING SUM(rating) > 0
    ORDER BY SUM(rating) DESC
    LIMIT max_size;

CREATE TEMP TABLE recommended ON COMMIT DROP 
AS
SELECT trackid, lower('recommended')
FROM ratingrecord finalRate
    INNER JOIN 
    (
        SELECT otherRate.userid AS otherUserId
             , SUM(myRate.rating * otherRate.rating) as SumRating 
        FROM ratingrecord AS myRate
        INNER JOIN ratingrecord AS otherRate 
        ON myRate.trackid = otherRate.trackid
        WHERE myRate.userid = puserid AND myRate.userid != otherRate.userid         
        GROUP BY otherRate.userid
        HAVING SUM(myRate.rating * otherRate.rating) > 0
    )  AS userRelations 
    ON finalRate.userid = userRelations.otherUserId
WHERE finalRate.trackid NOT IN (SELECT trackid FROM ratingrecord WHERE userid = puserid)
GROUP BY finalRate.trackid
HAVING SUM(finalRate.rating * userRelations.SumRating) > 0
ORDER BY SUM(finalRate.rating * userRelations.SumRating) DESC
LIMIT max_size;

RETURN QUERY SELECT * FROM recommended;

-- another RETURN QUERY statements

END;    
$BODY$ 
LANGUAGE plpgsql VOLATILE;
我希望在结果集中使用类似于ORDER BY random LIMIT max_size的内容,但不知道将其放置在何处。

或者使用UNION ALL组合纯SQL中的所有子查询,并在末尾添加ORDER BY random LIMIT n一次

或者您必须跟踪plpgsql中自己返回的行数,如下所示:

CREATE OR REPLACE FUNCTION android_getproposedsongs_test(puserid varchar, max_size int)
  RETURNS TABLE(sid uuid, method text) AS
$func$
DECLARE
   song_count int;  -- I'd rather not use spurious capitalisation
   running_ct int := 0;
   ct         int;
BEGIN

RETURN QUERY SELECT ... LIMIT max_size; -- apply to each individual query!

GET DIAGNOSTICS ct = ROW_COUNT;
running_ct := running_ct + ct;
IF running_ct >= max_size THEN
   RETURN;
END IF;

RETURN QUERY SELECT ... LIMIT max_size;

GET DIAGNOSTICS ct = ROW_COUNT;
running_ct := running_ct + ct;
IF running_ct >= max_size THEN
   RETURN;
END IF;

-- another RETURN QUERY statements

END 
$func$ LANGUAGE plpgsql VOLATILE;
相关的:

但是,这只返回前N行,而不是随机选择。要实现这一点,请在下一步中返回所有符合条件的行(无限制),并按随机限制n应用顺序:

SELECT *
FROM   android_getproposedsongs_test('foo', 3)
ORDER  BY random() LIMIT 123;
您必须知道,获取随机行的成本可能要高得多,因为必须首先确定所有可能的多个候选行。返回前N行要便宜得多