Sybase的分页,可以说,不是一般的难做。因为这数据库本身,支持太差。搞不懂为什么一个商业数据库,这么基本的功能,都弄的这么难做。
想起一段话:做简单的事情要简单,复杂的事情要能做。
分页查询,应该归入简单的事情吧!
在网上找到的,关于分页查询的SQL,看上去都挺有道理的,放到Sybase上一跑,就发现,几乎全部不能运行,直接给你报错。
我认为问题主要集中在Sybase对子查询的支持上。Sybase对子查询的支持,非常非常的有限。所以,先说说Sybase对子查询的支持吧!
网上有一篇博客,写的不错,说的是Sybase支持与不支持的子查询:
当我看到支持 >, <, in, not in 的子查询时,有点狂喜,认为一句SQL能搞定分页的。于是,我欣喜的写下以下2种方案:
方案一(不能用的哦):
select top <pageSize> *
from <table>
where <id> > (select max(<id>)
from (select top (<pageSize> * (<pageNum> - 1))
from <table>
order by <id>)
order by <id>)
order by <id>
方案二(同样不行的哦):
select top <pageSize> *
from <table>
where <id> not in (select top (<pageSize> * (<pageNum> - 1))
from <table>
order by <id>)
order by <id>
想归想,写的时候,就发现 方案一 很不靠谱。在子查询里面 再用 子查询,并且 还用在from里面,不靠谱,很不靠谱。一运行,果然不能跑。
方案二,看上去挺好,只有一个子查询,并且是Sybase支持的类型,是真支持的。但是(不好意思,还是转折了),很遗憾的告诉你,也是不能跑的。
这个方案有2个问题:
1、子查询中,用了top。Sybase的子查询中,不能用top的,测了才知道;
2、子查询中,用了order by。Sybase的子查询中,是不能用order by的,测了才知道。
现在看来,除了写存储过程外,真的没办法了。
但是,不愿意用存储过程。
只能分多条SQL来完成这一件事。
于是,就出现了以下方案:
方案三(可以用):
select top (<pageSize> * (<pageNum> - 1))
from <table>
order by <id>
从上面SQL中取出 max(id)
select top <pageSize> *
from <table>
where <id> > max(id)
order by <id>
这样分2个SQL,在数据库之外,找出前N-1页最大的ID,作为第2个SQL的条件,来完成分页查询。
虽然麻烦点,也算是一种解决方案吧!
暂时还没想到更好的方案,谁有的话,告诉我呀。
Reference:
http://lippeng.iteye.com/blog/1555237