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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.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
Sql 使用select查询连接postgres中的系列_Sql_Postgresql_Random_Row Number_Generate Series - Fatal编程技术网

Sql 使用select查询连接postgres中的系列

Sql 使用select查询连接postgres中的系列,sql,postgresql,random,row-number,generate-series,Sql,Postgresql,Random,Row Number,Generate Series,我正在寻找连接这两个查询(或同时运行这两个查询)的方法: 使用此查询: SELECT id FROM foo ORDER BY RANDOM() LIMIT 50; 在某种程度上,我得到了50行,如下所示: series, ids_from_foo 1, 53 2, 34 3, 23 我已经做了几天了,我想不出来。任何帮助都很好。使用行号() 从随机排序的表中选取前n行是一种简单、简短、粗暴的方法,但也是随机选取50行的慢方法。所有行都必须按这种方式排序 它适用于中小型表或一次性临时使用。对

我正在寻找连接这两个查询(或同时运行这两个查询)的方法:

使用此查询:

SELECT id FROM foo ORDER BY RANDOM() LIMIT 50;
在某种程度上,我得到了50行,如下所示:

series, ids_from_foo
1, 53
2, 34
3, 23
我已经做了几天了,我想不出来。任何帮助都很好。

使用
行号()


从随机排序的表中选取前n行是一种简单、简短、粗暴的方法,但也是随机选取50行的方法。所有行都必须按这种方式排序

它适用于中小型表或一次性临时使用。对于在表上重复使用,有更有效的方法。 如果主键中的间隙/孤岛比率较低,请使用以下选项:

SELECT row_number() OVER() AS rn, *
FROM (
   SELECT *
   FROM  (
       SELECT floor(random() * 999999)::int AS foo_id
       FROM   generate_series(1, 55) g
       GROUP  BY 1                     -- trim duplicates
       ) sub1
   JOIN   foo USING (foo_id)
   LIMIT  50
   ) sub2;
这将是毫秒(或更短)的问题,无论表格有多大
使用
解释分析
将性能与备选解决方案进行比较

解释
  • 999999
    是表的估计行数,向上舍入。替换为以下结果:

    SELECT reltuples FROM pg_class WHERE oid = 'foo'::regclass;
    
    四舍五入,方便地包含自上次
    分析以来可能出现的新条目。您还可以在通用查询中动态使用表达式本身,这很便宜。详情:

  • 55
    是结果中所需的行数(
    50
    ),乘以一个较低的系数,以轻松弥补表中的间距比率,以及(不太可能但可能)重复的随机数

  • 不言而喻,
    foo_id
    必须被索引。主键的作用很好

  • 如果主键不在1附近开始(不必精确为1,间隙已覆盖),请将最小pk值添加到计算中:

    min_pkey + floor(random() * 999999)::int
    
详细解释在此相关回答中:


谢谢你的帮助。我希望有一些东西能保持序列的顺序,同时又能使ID不受foo的随机性和差异性的影响。@newusername新版本能满足您的需要吗?是的。我向你致敬。你真的很快,所以2分钟后我就可以接受你的答案了。非常感谢。当我第一次从MySQL迁移到Postgres时,MVCC行数问题让我抓狂。现在MySQL让我发疯了。很好的解释(在另一篇文章中也有)。另一个有趣的问题是,没有等价的generate_系列,任何RDBMS如何生存?@JohnBarça“generate_系列”可以通过从任何足够大的表中选择行号来模拟。此外,还有其他特定于DB的方法来替换
生成_系列
,如
按级别连接@IgorRomanchenko。没错,但从现有表中选择行并不是一个真正的等效解决方案,显然,如果您愿意付费,您可以在Oracle中做任何事情。我的评论更多地针对SQL Server和MySQL。
SELECT reltuples FROM pg_class WHERE oid = 'foo'::regclass;
min_pkey + floor(random() * 999999)::int