5

我正在 ColdFusion 中编写一个函数,它返回与用户输入匹配的前几条记录,以及整个数据库中匹配记录的总数。该功能将用于提供自动完成功能,因此速度/效率是其最关心的问题。例如,如果函数接收到 input "bl",它可能会返回{sampleMatches:["blue", "blade", "blunt"], totalMatches:5000}

出于速度目的,我尝试在单个查询中执行此操作,并最终得到如下所示的内容:

select record, count(*) over ()
from table
where criteria like :criteria
and rownum <= :desiredCount

这个解决方案的问题是它count(*) over ()总是返回 的值:desiredCount。我在这里看到了一个与我类似的问题,但我的应用程序没有创建临时表的权限。那么有没有办法在一个查询中解决我的问题?有没有更好的方法来解决它?谢谢!

4

2 回答 2

5

我是在脑海中写下这篇文章,所以你绝对应该安排这个时间,但我相信使用以下 CTE

  • 只需要你写一次条件
  • 只返回您指定的记录数量
  • 将正确的总计数添加到每条记录
  • 并且只评估一次

SQL 语句

WITH q AS (
  SELECT record
  FROM   table
  WHERE  criteria like :criteria
)
SELECT q1.*, q2.*
FROM   q q1
       CROSS JOIN (
         SELECT COUNT(*) FROM q
       ) q2
WHERE  rownum <= :desiredCount
于 2013-10-17T19:05:21.340 回答
3

嵌套子查询应该返回你想要的结果

select record, cnt
  from (select record, count(*) over () cnt
          from table
         where criteria like :criteria) 
 where rownum <= :desiredCount

但是,这将强制 Oracle 完全处理查询以生成准确的count. 如果您尝试执行自动完成,这似乎不太可能是您想要的,特别是当 Oracle 可能决定对tableif :criteriais进行表扫描会更有效,b因为该谓词的选择性不够。您真的确定需要对结果数量进行完全准确的计数吗?您确定您的表足够小/您的系统足够快/您的谓词有足够的选择性,以至于您可以实际满足这一要求吗?是否有可能返回一个不太昂贵(但不太准确)的行数估计值?或者限制count到更小的东西(比如 100 个)并让 UI 显示类似“和 100 多个结果”之类的东西?

于 2013-10-17T19:13:51.630 回答