求最小空号算法!

SassyBoy 2007-05-23 03:52:59
假设表tb(id varchar(4)),id可重复。
1.有1(001)的记录
a(不连续)."A001","A001","A003"->取得"A002"
b(连续的)."B001","B002"->取得"B003"
2.没有1的记录
"C003"->取得"C001"
3.没有的记录
假设"Dxxx"是不存在的->取得"D001"

现在要得到ABCD各类的最小空号就是"A002","B003","C001","D001"

请大虾指教,第2点没弄出来-_-#!...
...全文
1155 31 打赏 收藏 转发到动态 举报
写回复
用AI写文章
31 条回复
切换为时间正序
请发表友善的回复…
发表回复
wcbgyjs 2007-05-25
  • 打赏
  • 举报
回复
做个总结:
declare @t table(code varchar(6))
insert into @t select 'A001'
insert into @t select 'A001'
insert into @t select 'A003'
insert into @t select 'B001'
insert into @t select 'B002'
insert into @t select 'D003'

declare @s table(code varchar(6))
insert into @s
select 'A' union all
select 'B' union all
select 'C' union all
select 'D' union all
select 'F'

select
a.m+right(rtrim(min(a.n)+1001),3) as newCode
from
(select left(code,1) as m,cast(right(code,3) as int) n from @t
union
select code,0 from @s) a LEFT JOIN @t B on left(B.code,1)=a.m and right(B.code,3)=a.n+1
where B.code is null
group by
a.m

chenhexi007 2007-05-25
  • 打赏
  • 举报
回复
都是厉害的角啊,mark!
laifangsong 2007-05-25
  • 打赏
  • 举报
回复


/*取最小空号*/

------函数------
drop function dbo.numToStr
go
create function dbo.numToStr(@num int)
returns char(3)
begin
declare @str char(3)
declare @sNum varchar(3)
set @sNum=cast(@num as varchar)
if len(@sNum)=1
set @str = '00'+@sNum
else if len(@sNum)=2
set @str = '0'+@sNum
else
set @str = @sNum
return @str
end
go
drop function dbo.strToNum
go
create function dbo.strToNum(@str char(3))
returns int
begin
declare @num int
if substring(@str,1,2)='00'
set @num=cast(substring(@str,3,1) as int)
else if substring(@str,1,1)='0'
set @num=cast(substring(@str,2,2) as int)
else
set @num=cast(@str as int)
return @num
end
go
------函数------

select
case
when min(dbo.strToNum(substring(id,2,3)))<>1 then (select left(id,1)+'001' from konghao as c where left(c.id,1)=left(konghao.id,1))
else
(select top 1 left(a.id,1)+dbo.numToStr((dbo.strToNum(substring(a.id,2,3))+1)) from konghao as a where left(a.id,1)=left(konghao.id,1) and not exists(select 1 from konghao as b where left(b.id,1)=left(a.id,1) and b.id=left(b.id,1)+dbo.numToStr(dbo.strToNum(substring(a.id,2,3))+1)))
end
as maxUnUsedID

from konghao group by left(id,1)
SassyBoy 2007-05-25
  • 打赏
  • 举报
回复
看来大家还是挺热心的...我改了一下已经搞好了,谢谢大家了。
lxw7131 2007-05-24
  • 打赏
  • 举报
回复
正确的解法是:
1. 首先得有一个专门的表指出你所有的类名,因为这个题目要求未出现的项,即集合的补集,那就先得给出全集。例如是A B C D, 还是A B C D E F, 或者根本没有规律如A E G T X Y。假设这个表名是CLASSNAME。
2. 想办法把你的三种情况变成一种,这样就可用一条SQL语句来产生输出。办法很简单,在你的原数据中加入所有类的000纪录,实际上,这是一种修改边界条件的方法,这样一来,只有一种情况了,那就是查找最小的未使用编号了。语句如下(假设你的数据表名是CLASSDATA)
select left(code,1) as m,cast(right(code,3) as int) n from CLASSDATA
union
select CODE,0 from CLASSNAME
3. 对上面语句产生的表做查询,找出每类中后面没有连续值的所有编号中最小的那个,具体写法可参见libin_ftsafe(子陌红尘)回帖的语句。
lxw7131 2007-05-24
  • 打赏
  • 举报
回复
libin_ftsafe(子陌红尘)回帖的语句不具有通用性,比如
union
select char(ascii(max(left(code,1)))+1)+'001' from @t
确实输出了D001这个值,但只适用于帖子中这个例子,因为他的语句会直接产生一条某类001的结果,该类字母比原数据中出现的最大字母大1。
如果数据中C类中没有数据,而D类中有D001,那么他的语句执行结果会有以下错误:
1. 没有C001的输出
2. 出现了E001输出,而E类是不存在的。
woooooooow 2007-05-24
  • 打赏
  • 举报
回复
mark
yangjianw2004 2007-05-24
  • 打赏
  • 举报
回复
佩服!!
zhaobin163net 2007-05-24
  • 打赏
  • 举报
回复
create Procedure GetNextID(@inStr char(1))
as

declare @mPID char(4),
@mFilter char(2),
@nTmpID int

set @mFilter = @inStr+'%'
select ID=Identity(int,1,1),a.* into #tmp
from (select distinct Col from t1 where COl like+@mFilter)a

if exists(select top 1 * from #tmp)
begin
select top 1 @nTmpID=ID from #tmp where ID<>Convert(int,right(Col,3))
if @@rowCount=0
select @nTmpID=max(ID)+1 from #tmp

if @nTmpID<10
set @mPID = @inStr+'00'+Convert(Char(1),@nTmpID)
else if @nTmpID<100
set @mPID = @inStr+'0'+Convert(Char(1),@nTmpID)
else if @nTmpID<1000
set @mPID = @inStr+Convert(Char(1),@nTmpID)

end
else
set @mPID = @inStr+'001'

drop table #tmp
select @mPID

Go

--exec GetNextID 'A'
--exec GetNextID 'B'
--exec GetNextID 'C'
--exec GetNextID 'D'
SassyBoy 2007-05-24
  • 打赏
  • 举报
回复
是不难啊,但还是要动动脑筋...
dairy1 2007-05-24
  • 打赏
  • 举报
回复
把A/B/C/D 与后面的数字分开,数字由01开始一直循环到提交的数字,看有空就用啊。再拼起来用。这个题只是复杂一点,并不难
SassyBoy 2007-05-24
  • 打赏
  • 举报
回复
哈,用户的需求是千变万化的:)
寻道模式 2007-05-24
  • 打赏
  • 举报
回复
这样的题目你们怎么碰到的?
kaper 2007-05-23
  • 打赏
  • 举报
回复
呵呵 和我刚做完的咚咚有点象
A01/001 A01/002 A01/003
A02/001 A02/002 A02/003
A03/001 A03/002 A03/003
B01/001 B01/002 B01/003
B02/001 B02/002 B02/003
areswang 2007-05-23
  • 打赏
  • 举报
回复
MARK!
suifix 2007-05-23
  • 打赏
  • 举报
回复
create table tb([id] varchar(4))

insert tb values('A001')
insert tb values('A001')
insert tb values('A003')
insert tb values('B001')

insert tb values('B002')




declare @c char(1) , @cID varchar(4)

select @c = 'A'
if not exists(select 1 from tb where [id]=@c+'001')
begin
select @cID=@c+'001'
end
else
begin
select @cID= min([id]) from tb where left([id],1)=@c and cast(right([id],3) as int)+1 not in (select cast(right([id],3) as int) from tb where left([id],1)=@c)
select @cID = @c + right('000'+ltrim(rtrim(cast(cast(right(@cID,3) as int)+1 as char(3)))) ,3)
end

select @c,@cID
drop table tb
bill024 2007-05-23
  • 打赏
  • 举报
回复
钻石真漂亮
-狙击手- 2007-05-23
  • 打赏
  • 举报
回复
再佩服一下
SassyBoy 2007-05-23
  • 打赏
  • 举报
回复
钻石就是不一样...呵呵
wgsasd311 2007-05-23
  • 打赏
  • 举报
回复
佩服
加载更多回复(11)

34,594

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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