| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1656 人关注过本帖
标题:求寻找空缺的序号
只看楼主 加入收藏
ptyy803
Rank: 2
来 自:上海
等 级:论坛游民
威 望:2
帖 子:193
专家分:64
注 册:2009-6-11
结帖率:100%
收藏
已结贴  问题点数:20 回复次数:23 
求寻找空缺的序号
如下图,求下列图表中自上而下的序号最小的空缺号,如图中空缺的4
图片附件: 游客没有浏览图片的权限,请 登录注册


[ 本帖最后由 ptyy803 于 2012-6-17 21:58 编辑 ]
2012-06-17 21:57
arefeng
Rank: 2
等 级:论坛游民
帖 子:69
专家分:61
注 册:2012-5-30
收藏
得分:0 
按图示内容做两个方案给楼主参考:

方案一: 做一个自定义函数强行取值, 假设函数名为 min_zyh, 代码如下:
程序代码:
Func min_zyh
Local tmp*
If !Used("tmp_ypjgk")
    Use ypjgk In 0 Again Shar Alia tmp_ypjgk    && 这么做的目的是不让函数干扰源表的记录指针
Endi
Sele tmp_ypjgk
set order to zyh               && 关键, 需要确保对 zyh 字段进行索引 ( 这里假设索引名为 zyh )
m.tmp = 0
Scan                           && 此时的全表扫描, 记录指针已经受控于前面的 set order to 了.
    m.tmp = m.tmp + 1          && 这里假设楼主的表中序号为数值型字段并且序号增量为 1
    If zyh <> m.tmp            && 进行比对, 不吻合则意味着序号缺失
        Retu m.tmp             && 发现了空缺的序号时, 返回这个序号
    Endi
Ends
Retu m.tmp + 1                 && 没有发现空缺的序号, 则返回最大序号 + 1 作为新序号
这个方案非常可靠, 使用也简单, 在需要用到这个序号的地方写上 min_zyh() 即可.
但是, 严重不推荐, 因为性能方面有太多隐患, 仅适用于数据量不太大的情况下(单机百万记录以下).

方案二: 假设楼主项目中的序号空缺是因为删除记录造成, 可以考虑维护一个"被删除的序号表",
这样当需要重用已删除的序号时,
直接到这个表中取最小值就行了.
具体代码这里略掉吧, 有思路应该足够了.

总结: 将删除的序号进行重用总体来说不是好的方案, 虽然不是很清楚楼主的意图, 但基本可以肯定这种思路在很多方面都不能达成理想效果.

[ 本帖最后由 arefeng 于 2012-6-18 00:45 编辑 ]
2012-06-17 23:18
tlliqi
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:204
帖 子:15453
专家分:65956
注 册:2006-4-27
收藏
得分:0 
select (zyh+1) as 漏掉的号 fromwhere (zyh+1) not in(select zyh fromwhere zyh<22)
2012-06-18 08:33
sdta
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:江苏省连云港市
等 级:版主
威 望:335
帖 子:9841
专家分:27213
注 册:2012-2-5
收藏
得分:0 
程序代码:
CLEAR
CREATE CURSOR TABNAME (ZYH N(2))
FOR I=1 TO 21
    IF NOT INLIST(I,4,10,16)
       INSERT INTO TABNAME VALUES(I)
    ENDIF
ENDFOR
*---上面的代码是为了演示用,可以不要
SELECT ZYH FROM TABNAME ORDER BY ZYH INTO CURSOR TABNAMEA &&对记录进行排序(如果ZYH是无序的,如果有序可不要该行代码)
*---下面的代码是针对施主所提问题处理的(不同情况,处理方法不同)
SCAN
   IF ZYH!=RECNO()
      ? "最小的空缺号:",ZYH-1
      EXIT
   ENDIF
ENDSCAN


[ 本帖最后由 sdta 于 2012-6-18 10:12 编辑 ]

坚守VFP最后的阵地
2012-06-18 09:54
arefeng
Rank: 2
等 级:论坛游民
帖 子:69
专家分:61
注 册:2012-5-30
收藏
得分:0 
回复 3楼 tlliqi
这样不能达成楼主的要求: 最小的序号,
只能得到一个查询结果集, 包含了全部缺失的序号,
另外 select 子句中的条件 zyh < 22 不合理, 实际应用中不可能作这种限定.
所以如果要使用这个思路, 需要调整如下:
程序代码:
Select (zyh+1) As 漏掉的号 FromInto Cursor tmp_cur Where (zyh+1) Not In(Select zyh From 表)        && 使用临时表tmp_cur存储临时结果
Select tmp_cur
Calculate Min(漏掉的号) To min_zyh        && 用变量 min_zyh 存放最小序号
Use                                  && 关闭临时表


但是不推荐用这种方案, 等于在任何情况下都做了完整的全表扫描, 哪怕第一个序号就缺号也扫描, 效率极低.

[ 本帖最后由 arefeng 于 2012-6-18 13:55 编辑 ]
2012-06-18 10:12
arefeng
Rank: 2
等 级:论坛游民
帖 子:69
专家分:61
注 册:2012-5-30
收藏
得分:0 
回复 4楼 sdta
不科学啊, 主要是用select生成重新排序后的临时表的方法不合理.

如果源表记录数很多的话,这种排序法太浪费了,实在没有必要.
2012-06-18 10:52
sdta
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:江苏省连云港市
等 级:版主
威 望:335
帖 子:9841
专家分:27213
注 册:2012-2-5
收藏
得分:0 
回复 6楼 arefeng
单机程序记录数不会很多的,如果很多就不会出现这种情况了。个中原因自己去想吧。

[ 本帖最后由 sdta 于 2012-6-18 11:03 编辑 ]

坚守VFP最后的阵地
2012-06-18 11:01
tlliqi
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:204
帖 子:15453
专家分:65956
注 册:2006-4-27
收藏
得分:0 
回复 5楼 arefeng
那只是给个示例
自己要会变通才行
2012-06-18 12:55
hgfeng1984
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:5
帖 子:139
专家分:513
注 册:2006-3-26
收藏
得分:0 
以下是引用tlliqi在2012-6-18 12:55:23的发言:

那只是给个示例
自己要会变通才行
如果只找最小的号,你的代码完全可以.
2012-06-18 13:46
cnfarer
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:179
帖 子:3330
专家分:21157
注 册:2010-1-19
收藏
得分:0 
locate for zyh>recn()
?"最小空缺号:",recn();

原来写错了不是recc()而该是recn()

[ 本帖最后由 cnfarer 于 2012-6-19 06:15 编辑 ]

★★★★★为人民服务★★★★★
2012-06-18 14:07
快速回复:求寻找空缺的序号
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.019003 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved