SQL 限制与扩展

标签 sql postgresql sqlalchemy sql-limit

有没有一种方法可以像 LIMIT 一样限制选择,但不是用偏移量返回限制,而是用“spread”进行限制。

例如,如果一个选择返回 1000 行,而我将其限制为 100,那么我从开始到结束每 10 行都会得到一次。

我知道这需要执行完整的SELECT,因为 RDBMS 需要遍历所有行才能执行此操作。但是,例如,当我需要每 100 行时,不是返回 100000 行,而是会减少很多传输,并且可以在 RDBMS 上完成工作。

我需要在 PostgreSQL 数据库上执行此操作。

最佳答案

没有内置语法可以执行与LIMIT / OFFSET相关的操作。 (也不适用于标准 SQL FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } { ONLY | WITH TIES }])。

您可以通过 modulo operator % 实现您的目标:

SELECT *
FROM (
   SELECT row_number() OVER () AS rn, ... original SELECT list
   FROM ... -- original query
   ) sub
WHERE rn%10 = 0  -- every 10th row

由于窗口定义中没有ORDER BY,因此根据查询的ORDER BY分配行号。
如果根本没有ORDER BY,您将得到任意的行顺序。这仍然是某种命令,结果并不在你的掌控之中。

您可以使用TABLESAMPLE在单个表格上应用这种过滤器。语法。

SELECT * FROM tbl TABLESAMPLE SYSTEM (10);  -- roughly 10 %

或者:

SELECT * FROM tbl TABLESAMPLE BERNOULLI (10);  -- roughly 10 %

SYSTEM 速度更快,BERNOULLI 更加随机。

您甚至可以在同一查询中的多个表上应用TABLESAMPLE过滤器,例如:

SELECT *
FROM tbl1 TABLESAMPLE SYSTEM (10)
JOIN tbl2 TABLESAMPLE BERNOULLI (10) USING (big_id);

但是生成的行数可能会有很大差异。要获取给定的行数,请考虑附加模块 tsm_system_rows反而。请参阅:

关于SQL 限制与扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70398543/

相关文章:

mysql - 如何将 mysql 输入复制到另一个表?

mysql - 在mysql查询中找到多行的最大列集

json - postgres 存储对 json 中字段的引用

mysql - 外键和基本关系表

flask - 如何使用 SQlAlchemy 声明方式插入数据

python - 使用 Python 打开文本文件并另存为 SQL 文件

sql - PostgreSQL 中的相关 SERIAL 列

sql - 带有 SQL 查询的函数没有结果数据的目的地

postgresql - 如何使用 Yesod/Persistent 创建外键约束?

mysql - SQLAlchemy 可以独立于框架单独使用吗?是否推荐这样做?