有没有简单的方法在sybase中实现分页? 在postgres中有mysql的限制和偏移,有限制X,Y。那么sybase呢?有一个限制结果的顶级约束,但要实现完全分页,还需要抵消。 如果有几个pags,这不是问题,我可以简单地在客户端调整结果,但如果有数百万行,我只想获取我需要的数据。
答案 0 :(得分:4)
// First row = 1000
// Last row = 1009
// Total row = 1009 - 1000 + 1 = 10
// Restriction: exec sp_dboption 'DATABASE_NAME','select into/bulkcopy','true'
select TOP 1009 *, rownum=identity(10)
into #people
from people
where upper(surname) like 'B%'
select * from #people where rownum >= 1000
drop table #people
// It shoulde be better SQL-ANSI-2008 (but we have to wait):
// SELECT * FROM people
// where upper(surname) like 'B%'
// OFFSET 1000 ROWS FETCH NEXT 10 ROWS ONLY
答案 1 :(得分:3)
引自http://www.isug.com/Sybase_FAQ/ASE/section6.2.html#6.2.12:
Sybase没有直接等同于Oracle的rownum,但在很多情况下可以模拟其功能。
您可以设置最大rowcount
,这将限制任何特定查询返回的行数:
set rowcount 150
该限制将适用,直到重置:
set rowcount 0
您可以选择临时表,然后从中提取数据:
set rowcount 150
select pseudo_key = identity(3),
col1,
col2
into #tempA
from masterTable
where clause...
order by 2,3
select col1,col2 from #tempA where pseudo_key between 100 and 150
您可以通过仅存储ID列来优化临时表上的存储,然后将其连接回原始表以供选择。
常见问题解答还提出了其他解决方案,包括游标或Sybperl。
答案 2 :(得分:2)
我参加聚会很晚,但是我偶然发现了这个问题,并使用sybase doc中的TOP和START AT找到了更好的答案。您需要将ORDER BY用于,否则结果将无法预测。
http://dcx.sybase.com/1101/en/dbusage_en11/first-order-formatting.html
选择前2位开始于5 * 来自员工 按姓氏顺序排列;
答案 3 :(得分:0)
不幸的是,Sybase不提供设置启动和偏移限制的功能。您可以实现的最佳方法是使用SET ROWCOUNT来限制返回的记录数。如果您有1,000条记录并希望按50个条目分页,那么这样的内容将带回第一页......
set rowcount 50
select * from orders
第二页......
set rowcount 100
select * from orders
...然后您可以选择不在Java代码中显示前50个。显然,当您向前翻页时,您最终必须返回越来越大的数据集。关于如何处理1,000,000条记录的问题对于分页的用户界面似乎不实用。没有用户在Google上搜索,然后向前翻页1000次寻找内容。
如果我有自然钥匙怎么办?
如果您确实拥有相对较大的数据集,并且可以在数据上使用自然键,这将有助于限制返回的记录。例如,如果您有一个联系人列表,并且有一个界面允许您的用户选择A到Z来根据Surname对目录中的人进行寻呼,那么您可以执行以下操作...
set rowcount 50
select * from people
where upper(surname) like 'B%'
如果有超过50个姓氏以'B'开头的人,请使用与上述相同的方法向前翻页......
set rowcount 100
select * from people
where upper(surname) like 'B%'
...并删除Java代码中的前50个。
继续此示例之后,您可以按日期限制搜索,或者根据您的用户需求限制其他一些数据。
希望这有帮助!
答案 4 :(得分:0)
您可以尝试使用两次设置ROWCOUNT:
declare @skipRows int, @getRows int SELECT @skipRows=50 SELECT @getRows=10 set ROWCOUNT @skipRows SELECT caslsource_id into #caslsource_paging FROM caslsources set rowcount @getRows Select * from caslsources where caslsource_id not in (select caslsource_id from #caslsource_paging) DROP TABLE #caslsource_paging
这会创建一个要跳过的临时行表。您需要将WHERE和ORER BY子句添加到两个SELECT中以跳过正确的页面。
答案 5 :(得分:0)
Sybase SQL Anywhere示例,每页行数:10,偏移量:1000。
SELECT top 10 start at 1001 * FROM employee order by employeeid
注意:您需要指定order by
列。
答案 6 :(得分:0)
我不知道这是ASE还是其他产品,但是以下模式可在我使用过的多个数据库中运行,只要有一种方法可以以某种方式生成带有行号的临时表,并且您可以确定每行的唯一键:
输入参数:
declare @p_first int /* max number of rows to see; may be null (= all results); otherwise must be positive number */
declare @p_skipFirst int /* number of rows to skip before the results; must be nonnegative number */
declare @p_after PKTYPE /* key for the row before you start skipping; may be null */
给了一张桌子
RowNumber | RowIndex | DataCol1
1 | 1234 | Joe
2 | 1235 | Sue
3 | 2000 | John
4 | 2005 | Frank
5 | 3000 | Tom
6 | 4000 | Alice
参数集:
set @p_first = 5
set @p_skipFirst = 2
set @p_after = 1235
将代表第5行和第6行。
另外一组参数可以反向表示从表末尾的分页:
declare @p_last int /* max number of rows to see; may be null (= all results); otherwise must be positive number */
declare @p_skipLast int /* number of rows to skip after the results; must be nonnegative number */
declare @p_before PKTYPE /* key for the row after you start skipping; may be null */
假设未排序的表位于#resultsBeforeSort
的索引列中,您可以使用以下脚本对此进行排序:
RowIndex
该脚本设置参数select RowNumber = identity(10), *
into #results
from #resultsBeforeSort
/*
you might also wish to have a where clause on this query
this sort is dynamically generated based on a sort expression and
ultimately ended with RowIndex to ensure a deterministic order
*/
order by Column1, Column2 desc, RowIndex
declare @p_total int, @p_min int, @p_max int
select @p_total = count(*) from #results
select @p_min = case when @p_after is null then 1 + @p_skipFirst else @p_total + 1 end
select @p_min = RowNumber + @p_skipFirst from #results where [RowIndex] = @p_after
select @p_max = case when @p_before is null then @p_total - @p_skipLast else 0 end
select @p_max = RowNumber - @p_skipLast from #results where [RowIndex] = @p_before
declare @p_min2 int, @p_max2 int
set @p_min2 = @p_min
set @p_max2 = @p_max
select @p_max2 = case when @p_first is null then @p_max else @p_min + @p_first - 1 end
select @p_min2 = case when @p_last is null then @p_min else @p_max - @p_last end
select @p_min = case when @p_min2 > @p_min then @p_min2 else @p_min end
select @p_max = case when @p_max2 < @p_max then @p_max2 else @p_max end
,@p_min
和@p_max
以及临时表@p_total
然后可以使用它来选择实际数据;选择2个表结果,第一个是元数据(之所以选择它,是因为第二个表可能没有任何实际行,并且您的阅读器实现可能无法处理而不回溯):
#results
紧随其后的是您实际想要的结果分页窗口:
select [Count] = @p_total,
HasPreviousPage = (case when @p_min > 1 then 1 else 0 end),
HasNextPage = (case when @p_max + 1 < @p_total then 1 else 0 end)
执行此通用解决方案可以显示所需的任何分页策略。您可以通过select [RowIndex], Col1, Col2, Col3
from #results where RowNumber between @p_min and @p_max
和@p_after
(或@p_first
和@p_before
)进行流媒体解决方案(facebook,google,stackoverflow,reddit等)。您可以使用@p_last
和@p_first
进行偏移+拍摄。您还可以使用相同的参数@p_skipFirst
和@p_first = size
来进行页面+尺寸的设置。此外,您还可以使用其他参数组合来执行更多深奥的分页策略(最后X页,在绝对记录之间,偏移量+定位符之间)。
这就是说,Sybase(SAP)ASE现在确实通过@p_skipFirst = (page - 1) * size
直接支持偏移+获取策略。如果您只希望支持该策略,则可以将以上内容简化为:
rows limit @p_first offset @p_skipFirst