当前位置: 首页 > 面试题库 >

在应用LIMIT之前获得结果计数的最佳方法

丁嘉
2023-03-14
问题内容

当分页来自数据库的数据时,您需要知道将要呈现多少页来呈现页面跳转控件。

目前,我通过运行两次查询来做到这一点,一次包裹在a中count()以确定总结果,第二次使用限制以仅获取我当前页面所需的结果。

这似乎效率低下。有没有更好的方法来确定在LIMIT应用之前将返回多少结果?

我正在使用PHP和Postgres。


问题答案:

纯SQL

自2008年以来情况发生了变化。您可以使用窗口函数在一个查询中获取全部计数 有限的结果。2009年PostgreSQL
8.4中
引入。

SELECT foo
     , **count(*) OVER() AS full_count**
FROM   bar
WHERE  <some condition>
ORDER  BY <some col>
LIMIT  <pagesize>
OFFSET <offset>;

请注意, 与没有总数相比 ,这 可能会贵得多 。必须对所有行进行计数,可能的快捷方式仅从匹配的索引中获取最前面的行可能不再有用。
小表或full_count<= OFFSET+没关系LIMIT。事关重大full_count

*_OFFSET 极端 _ *情况 :当至少等于基本查询的行数时, _ 返回 _ 任何行
。所以你也没有full_count。可能的替代方法:

  • 使用LIMIT / OFFSET运行查询,并获得总行数

SELECT查询中的事件顺序

(0. CTE是分别评估和实现的。在Postgres 12或更高版本中,计划者可以在上班之前内联诸如子查询之类的东西。)

  1. WHERE子句(和JOIN条件,尽管您的示例中没有条件)从基表中筛选合格的行。 其余部分基于过滤后的子集。

(2.GROUP BY和聚合函数将放在此处。)不在此处。

(3.SELECT基于分组/聚合的列评估其他列表表达式。)此处不行。

  1. 窗口函数的应用取决于OVER子句和函数的框架规范。简单count(*) OVER()基于所有符合条件的行。

  2. ORDER BY

(6.DISTINCT否则DISTINCT ON会去这里。)不在这里。

  1. LIMIT/OFFSET是基于已建立的顺序应用的,以选择要返回的行。

LIMIT/OFFSET随着表中行数的增加,效率变得越来越低。

获得最终计数的替代方法

有完全不同的方法来获取受影响的行的计数( _ 不是_OFFSET&之前的全部计数LIMIT)。Postgres具有内部记帐功能,其中最后一个SQL命令影响了多少行。一些客户端可以访问该信息或自己计算行数(例如psql)。

例如,使用以下命令执行SQL命令后,可以立即在 plpgsql中 检索受影响的行数:

GET DIAGNOSTICS integer_var = ROW_COUNT;

手册中的详细信息。

或者您可以pg_num_rowsPHP中 使用。或其他客户端中的类似功能。



 类似资料:
  • 问题内容: 当分页来自数据库的数据时,您需要知道将要呈现多少页来呈现页面跳转控件。 目前,我通过运行两次查询来做到这一点,一次包裹在a中以确定总结果,第二次使用限制以仅获取我当前页面所需的结果。 这似乎效率低下。有没有更好的方法来确定在应用之前将返回多少结果? 我正在使用PHP和Postgres。 问题答案: 纯SQL 自2008年以来情况发生了变化。您可以使用窗口函数在一个查询中获取全部计数 和

  • 问题内容: 我如何能够在oracle查询中为几个组获得N个结果。 例如,给定下表: 有更多行和更多职业。我想从每个职业中聘请三名员工(可以说)。 有没有不用子查询就可以做到这一点的方法? 问题答案: 这将产生所需的内容,并且不使用供应商特定的SQL功能(例如TOP N或RANK())。 在此示例中,它为三位雇员提供每个职业emp_id最低的值。您可以更改不等式比较中使用的属性,以使其按名称或其他方

  • 问题内容: 我需要选择一个字段以几个不同的前缀之一开头的行: 在Oracle或SQL Server中使用SQL的最佳方法是什么?我正在寻找类似以下语句的内容(不正确): 或者 编辑:我想看看如何通过在一个SELECT语句中提供所有前缀,或将所有前缀存储在帮助器表中来完成此操作。 前缀长度不固定。 问题答案: 将前缀表与实际表连接将在SQL Server和Oracle中都可以使用。

  • 问题内容: 例如,给定此表的稀疏ID: 我可以使用以下查询从表中获取最高的“ id”: 我得到: 我如何才能在最高“ id”之前获得“ id”(即使值不是连续的)? 问题答案: 是相同的 注意:这是事务性sql语法,根据您的供应商使用rownum或limit 获得第二行,你可以做

  • 问题内容: 我有一个员工表,如下所示: 我需要获取id等于4的问题的最小值和最大值。在这种情况下,我需要返回5和25。我使用以下查询实现了这一点: 但是,这不会返回的是问题ID。如何调整查询以显示q2是最小值,q4是最大值?我知道我可以写一个大写的语句,但是我也觉得可以使用联接来完成,但是我不知道。 注意:这是针对postgresql数据库的,但是我也标记了MySQL,因为我知道它也支持和函数。如

  • 问题内容: 插入行的最佳方法是什么? 我知道和和,但不明白连接到每个利弊。 有人可以解释这些差异以及何时使用它们吗? 问题答案: 返回在所有范围内为当前会话中的任何表生成的最后一个标识值。 您需要小心 ,因为它是跨作用域的。您可以从触发器获取值,而不是当前语句。 返回为当前会话和当前范围中的任何表生成的最后一个标识值。 通常,您要使用什么 。 返回在任何会话和任何作用域中为特定表生成的最后一个标识