我需要一个函数来从表中随机选择 88 行(没有重复项)



我有一个包含几列(id,description,created(时间戳(和ipaddress(的表。我已经插入了 200 行作为虚拟数据。我需要一种方法来从该表中抽取 88 个没有重复项的随机行。

我试过这个:

create or replace function GetRandomCrazy88() returns setof varchar(255) as
'
select description
from task
left join tagassignment t on task.id = t.taskid
order by random()
limit 88;
' language 'sql';

但这会返回重复的行。

我也试过这个(它有点失控(:

CREATE OR REPLACE FUNCTION GetRandomCrazy88(amount INTEGER)
RETURNS SETOF VARCHAR(255) AS
$$
DECLARE
tasklist INTEGER[] := '{}'::INTEGER[];
randomid INTEGER;
counter INTEGER := 0;
BEGIN
WHILE counter <= amount LOOP
SELECT CASE WHEN id = 0 THEN 1 ELSE id END INTO randomid
FROM ROUND(RANDOM() * (SELECT COUNT(*) - 1 FROM task)) AS id;
IF randomid = ANY(tasklist) OR ARRAY_LENGTH(tasklist, 1) IS NULL THEN
tasklist = array_append(tasklist, randomid);
counter := counter + 1;
ELSE
RAISE NOTICE 'DUPLICATE ID!!!';
END IF;
END LOOP;
RETURN QUERY SELECT description
FROM task t
WHERE t.id = ANY(tasklist);
END;
$$ LANGUAGE plpgsql
SECURITY DEFINER;

它在 while 循环中失败。它永远不会达到所需的 88 个数字,因为它无法在 if 语句中向数组添加任何内容,因为数组为空且具有 NULL 值。

有什么方法可以得到正好 88 个随机行,没有任何重复项?

以下是您可能喜欢的快速解决方案:

CREATE EXTENSION IF NOT EXISTS tsm_system_rows;
select * from task 
tablesample system_rows (88);

作为参考,TABLESAMPLE 在 SELECT 的文档中: https://www.postgresql.org/docs/current/sql-select.html

这是该功能的一个很好的文章:

https://www.2ndquadrant.com/en/blog/tablesample-in-postgresql-9-5-2/

。以及同一作者关于随机抽样的一般主题的另一篇文章:

https://www.2ndquadrant.com/en/blog/tablesample-and-other-methods-for-getting-random-tuples/

tsm_system_rows是两个标准采样扩展之一,记录如下: https://www.postgresql.org/docs/current/tsm-system-rows.html

嘿!我很高兴你问了这个问题。我倾向于使用BERNOULLI方法,该方法内置于SELECT中,但它基于百分比。我刚刚尝试了这个,它工作正常:

select * from task 
tablesample BERNOULLI (1)
limit 88

相关内容

  • 没有找到相关文章

最新更新