是否可以仅使用一个查询对Coldfusion中的页面进行分页和显示?
我的理解是你可以用一个查询进行分页,但是你需要一个额外的查询来创建页面。这是为了计算结果总数。
(currentPage - 1) * resultsPerPage = Offset in MySQL
查询。这个逻辑足以创建next / prev按钮。但是为了知道页面数量,我们不需要知道使用单独查询的结果总数,然后查询数据查询吗?
答案 0 :(得分:3)
在MS SQL中,使用CTE:
接收参数@startRow和@endRow以及你需要的参数
WITH qTemp AS (
select *
, count(*) as totCnt
, rowNum = ROW_NUMBER() OVER(ORDER BY myIndex ASC)
from myTable
where (my where clause)
)
SELECT * FROM qTemp
WHERE rowNum BETWEEN @startRow AND @endRow
答案 1 :(得分:2)
是的,典型的基于mysql的方法需要两个查询:一个使用select count(*) from table
,第二个使用select a, b, c from table limit x,y
,其中x和y是根据当前页面和所需的偏移量构建的。
使用单个查询,您需要选择所有记录,这在大多数案例中效率较低。
答案 2 :(得分:2)
我对MySQL并不熟悉,但我知道在MS SQL中,存储过程可以返回多个结果集。
如果你不能这样做,你提出了两种方法,但第二种方法可以优化。
首先,运行两个查询。一个用于获取当前显示页面的数据,一个用于获取结果集的总大小。如果数据频繁更改,或者通常不显示多个页面,我会这样做。这需要两次db调用,但会减少返回的总大小。如果您没有频繁更改数据,但每个查询很少使用多个页面,您还可以缓存总结果计数。
第二种是在一个大查询中返回所有结果,并且只显示相应的页面。您不需要在此查询查询,因为使用cfloop和cfoutput的查询循环可以指定开始和结束查询行。如果你这样做,我会缓存查询。这会占用更多内存,第一页加载速度会变慢,但后续页面上的页面加载速度很快。
答案 3 :(得分:2)
您只需使用CFGrid即可显示整个结果集。分页被烘焙。以下是文档的链接:http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7baf.html
答案 4 :(得分:2)
我所做的是做“大”查询并将结果存储在SESSION范围内,然后对每个页面进行查询查询。对数据库的调用较少,这通常是瓶颈所在。
答案 5 :(得分:2)
这通常是我如何做到的。您可以通过执行子选择并对其进行别名来选择表的计数。您可以将其视为此查询中的第三个列。如果您愿意,这可以用于从另一个表中获取数据。它确实会导致MySQL在查询过程中启动另一个查询来汇总数据,但是coldfusion只需要询问数据库一次,使其比2次单独查询更快。
<cfquery name="SomeQry" datasource="YourDatabase">
SELECT
col1,
col2,
(SELECT COUNT(*) FROM MyTable) as mycount
FROM MyTable
LIMIT #(CurrentPage * 20) - 20#, 20
</cfquery>
<cfset start = CurrentPage - 5>
<cfset Max = CurrentPage + 5>
<cfoutput>
<ul class="pagination">
<cfloop from=#start# to=#Max# index="page">
<li><a href="/search?q=#querystring#&page=#page#">#page#</a></li>
</cfloop>
</ul>
</cfoutput>
答案 6 :(得分:1)
我相信你可以做到:
SET @myCount = (SELECT COUNT(*) FROM tblName);
SELECT col1, col2, @myCount as 'total'
FROM tblName
在第二个查询中使用适当的分页内容。您将获得所返回集合中每条记录的计数,但这并不是什么大不了的事。我没有测试过这个,我没有MySQL。
答案 7 :(得分:1)
虽然这不是最好的方法,但这是旧学校的方式。
您可以使用cfoutput来完成此任务。
<cfquery name="q" dsn="#application.dsn">
SELECT
firstname,
lastname
FROM
mytable
WHERE
<some conditions>
</cfquery>
<cfparam name="url.maxrows" default="50">
<cfset url.maxrows = fix(val(url.maxrows))>
<cfparam name="url.startrow" default="1">
<cfset url.startrow = fix(val(url.startrow))>
<cfif url.startrow lte 0>
<cfset url.startrow = 1>
</cfif>
<cfif url.startrow gte q.recordcount>
<cfset url.startrow = q.recordcount>
</cfif>
<cfoutput>Total Records: #q.recordcount#/<cfoutput>
<cfoutput query="q" maxrows="#url.maxrows#" startrow="#url.startrow#">
#firstname#<br/>#lastname#
</cfoutput>
<p>Page:
<cfloop from="1" to="#q.recordcount#" step="#url.maxrows#" index="i">
<a href="#cgi.script_name#?startrow=#i#&maxrows=#url.maxrows">#(i / url.maxrows)#</a>
</cfloop>
</p>
现在说实话......这个方法很糟糕,对于大型查询来说真的很慢。我个人使用CFWheels拥有所有这些东西built into it's ORM。
答案 8 :(得分:1)
在MySQL中使用SQL_CALC_FOUND_ROWS
。例如:
SELECT SQL_CALC_FOUND_ROWS * FROM tbl WHERE x = y LIMIT s,m
在您的查询后再次查询:
SELECT FOUND_ROWS() AS TotalRows
使用指令SQL_CALC_FOUND_ROWS
会导致MySQL在应用限制和范围之前存储上次查询的总行数。这与在同一查询上执行Count()而不需要实际计算,然后查询,限制查询的开销相同。
在事务中包装两个db调用以确保它们连续执行。您可能还会考虑将查询抽象为一个函数,该函数将执行这两个操作并返回带有结果键和总行键的单个结构。使用上面引用的结果生成您认为合适的分页链接。