如何用 sql 语句每次取出一个大型数据表的 100 条记录?

NewCenturyNewPage 2004-09-14 05:46:09
我有一个用户表 : User(id,name ,age,sex,location)
该记录表大约有80万条记录,我现在要取出这个表的每条记录,对每天记录进行分析处理。

如果用: select * from User
肯定不行,等那80万条记录返回的时候,大约20分钟就过去了,浪费时间,而且内存说不定就撑破了。

现在我想这样做,我一次取出这个表的 100 条记录,逐次的取,一个个的分析。
直到所有的记录分析完毕。不知道怎么用 SQL 语句实现???

还有一个问题:我每次取出 100 条记录,我做了分析处理以后,我希望对User 表能否添加一个 flag虚拟字段,标识该记录已经被处理过了,下次取出时,如果发现flag标志为1, 我就不对它做处理。
不知道是否可行?
...全文
1134 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
CuteSword 2004-09-23
  • 打赏
  • 举报
回复
此贴受益匪浅。。。
CuteSword 2004-09-23
  • 打赏
  • 举报
回复
还有一个问题:同样是取第300到第400条记录,但是,
下面的两种写法:
1)select * from (select rownum rm,a.* from table_name a where rownum>=300) where rm<=400


2)select * from (select rownum rm,a.* from table_name a where rownum<=400) where rm>=300

大家认为结果一样吗?

呵呵,虽然逻辑上行得通,都是一样,但是只有第二种写法是正确的!
NewCenturyNewPage 2004-09-23
  • 打赏
  • 举报
回复
呵呵,看了上面这么多回答,我以为一楼的: truexf(小方) 方法最直观,也想当然的认为不会有问题。现在看来,他的那个回答是一个抛砖引玉的回复。

他那样做其实是错误的:
select * from xx WHERE ROWNUM >= num1 AND ROWNUM <= num2

你可以自己在oracle机子上测试,实际上这样执行的SQL语句根本不能产生结果记录集。
因为这里 ROWNUM 还没有定义他的范围。

我又试过用 dinya2003(OK) 的方法,发现这个方法其实很可靠。
--------------------------------------------------------------------------------------
取得第三百条到第四百条记录的写法,修改一下即可.

select * from (select rownum rm,a.* from table_name a where rownum<=400) where rm>=300
--------------------------------------------------------------------------------------

tanyun1111(TY) 的做法看起来有点复杂,我没有试,不知道正确不正确。

再次感谢大家的参与!
NewCenturyNewPage 2004-09-20
  • 打赏
  • 举报
回复
我还是考虑一次不取出全部的记录,一次取出 100 条记录,同时对数据表建立一个flag的新字段,这个字段是在数据库实际存在的字段。

我最初先把数据表所有的记录的flag标志位都置为0,
然后,我每次从数据库取 N 到 N+100条记录,对这100条记录进行分析,分析完毕,
把这100条记录的flag标志位置为1,继续取下100条记录。

等所有的记录都处理完毕,为了防止有的记录没有处理过,再做一次查询:
slecet * from user where flag =0;
只要还有flag标志位为0的记录,我就继续对该记录进行分析处理。
直到数据库所有的记录都处理完毕。


NewCenturyNewPage 2004-09-15
  • 打赏
  • 举报
回复
这样分页,我还有一个担心:
这样其实是静态分页的,也就是假设当前数据表是静态不变的,但是如果当前用户表 user 是动态变化的,即有用户不断的加入,也有用户需要注销, 那么上面的那种静态的分页方式是否就不可行了呢?

举例:当前有300个用户 user000-user300 ,但是这时又添加进来100 个用户,而原来的300 用户又有5个注销了,那么数据库是如何适应这样的改变的呢?
tanyun1111 2004-09-15
  • 打赏
  • 举报
回复
其实还有种分页排序方法:
select * from (select id,name ,age,sex,location,row_number() over (order by age) rn from User where ...) where rn between ((curPage-1)*pageSize+1) and curPage*pageSize;

其中:curPage是当前的页数,pageSize是每页想显示的条数。
当然你可以将pageSize设为100,就可以每次查出100条,而且是根据age排序的.
dinya2003 2004-09-15
  • 打赏
  • 举报
回复
取得第三百条到第四百条记录的写法,修改一下即可.

select * from (select rownum rm,a.* from table_name a where rownum<=400) where rm>=300
NewCenturyNewPage 2004-09-15
  • 打赏
  • 举报
回复
maohuijian(mao)
-------------------
你这样做,可行,但是实际运行的效率是很低的,因为你必须考虑到有进80万的用户表,如果你每次都去查你这个临时表tb,随着临时表的体积变大,那么查询需要的时间将越来越多,后来系统效率就大打折扣。

maohuijian 2004-09-15
  • 打赏
  • 举报
回复
我觉得这个虚拟字段可以另外建个表实现,没有必要非在原表上加啊
create table tb (
col2 varchar2(10)--和user表的id列属性相同
)
然后 用过程来处理数据,实现每次处理100条,并将处理过的记录的id 放在tb表中
tb表的col列标记是否处理过了
不知可否
ahui2k 2004-09-15
  • 打赏
  • 举报
回复
楼主你的情况怎么样了,我们遇到的问题很是相似,你要常发帖啊
NewCenturyNewPage 2004-09-15
  • 打赏
  • 举报
回复
所谓的虚拟字段:我是这么设想的,这个字段在oracle的原始数据库对应的数据表里面是不存在的,只是我临时运行程序的时候临时添加上去的,当我程序运行完毕,我仍然把这个字段把它给去掉。
biliky 2004-09-15
  • 打赏
  • 举报
回复
虚拟字段什么意思?程序中用到它,数据库中又不希望它存在?
ahui2k 2004-09-15
  • 打赏
  • 举报
回复
楼主和我遇到的问题简直一模一样
1,到底怎么加那个是否处理过的字段啊?
2,每次处理n条记录,如何写
biliky 2004-09-15
  • 打赏
  • 举报
回复
先建一个视图吧:
create view v_user as select rownum num,a.* from user a;
然后你就可以动态sql语句进行查询某些段的纪录:
start 、end为程序中变化的查询段的起始结束点。
EXECUTE 'select * from v_user where num between '||start||'and'||end';
baojianjun 2004-09-15
  • 打赏
  • 举报
回复
ROWNUM返回記錄數目的方法樓主可以搜索一下
dlab 2004-09-15
  • 打赏
  • 举报
回复
写plsql用cursor
NewCenturyNewPage 2004-09-15
  • 打赏
  • 举报
回复
up 一下。
yugboy 2004-09-14
  • 打赏
  • 举报
回复
你可以写一个plsql,定义一个cursor,循环着处理,每处理一条把flag标志为1,这样比较好实现
netcreator 2004-09-14
  • 打赏
  • 举报
回复
rownum是伪列!可以查询的
spotboy 2004-09-14
  • 打赏
  • 举报
回复
UP!
但是我怎么知道这个rownum,或者是说,rownum是非排序的,我怎么知道从哪个rownum开始选择呢?
加载更多回复(4)

17,377

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 基础和管理
社区管理员
  • 基础和管理社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧