function sb() { /*连接到数据库的代码:略*/ $sql="select id form `tablename` order by `id`; $result=mysql_query($sql); if($result) { $i=1; while($rs=mysql_fetch_array&&$i<=40000) { if($rs['id']==$i) return $i; $i++; } } return 40001; }不过这个应该好浪费空间?
楼上写错了,55555,应该是
function sb() { /*连接到数据库的代码:略*/$sql="select id form `tablename` order by `id`; $result=mysql_query($sql); if($result) { $i=1; while($rs=mysql_fetch_array&&$i<=40000) { if($rs['id']!=$i) return $i; $i++; } } return 40001; }把==换成!=。对不起啊,嘻嘻。
一个SQL语句就可以了 ---------------------------------------------------------- select min(id)+1 from 表名 t where not exists(select 1 from 表名 where id=a.id+1)
有个小错误,后边的a改成tselect min(id)+1 from 表名 t where not exists(select 1 from 表名 where id=t.id+1)
分批次查找啊,比如第一次 1-5000条 第二次 50001-10000条 。。 你想找出最小的数据, 你先伸序排列ID 从最小的匹配 ------------------------------------------------------ function sb() { /*连接到数据库的代码:略*/$sql="select id form `tablename` order by `id` asc $result=mysql_query($sql); if($result) { $i=1; while($rs=mysql_fetch_array&&$i<=40000) { if($rs['id']!=$i) return $i; $i++; } } return 40001; }
求最小的未被使用的ID set @c:=1 select id, @c:=@c+1 as p from tbl_name where @c+1>id order by p desc limit 1结果中的 p 就是所需结果
declare @t1 table(a int identity(1,1),b int) declare @t2 table(a int identity(1,1),b int) declare @i int set @i=0 while (@i<1000) begin insert into @t1 select 1 union select 2 union select 3 insert into @t2 select 1 union select 2 union select 3 set @i=@i+1 end delete from @t1 where a<100 and a >60 select top 1 a1.a from @t2 a1 left join @t1 b2 on a1.a=b2.a where b2.b is null纯粹路过,楼主有这意思
老大们写的语句太深奥了 set @c:=1 select id, @c:=@c+1 as p from tbl_name where @c+1>id order by p desc limit 1没看懂。
select count(id) from tablename where id<max对于这个max值,使用折半法。
如果只是暂时使用, 插入一个新field tmpid,先填入连续的整数1,2,3,。。 在该字段上建唯一索引, 然后使用 select min(id) from tablename where id>tmpid 当然插入新字段需要点时间,但是是一次性的,查询时速度会比较快
如果能修改表或建立临时表,我倒有一个解决办法~插入一个新field tmpid,用自增长填充select top 1 * from aaa where id<>tmpid order by id id返回tmpid就是最小的未被使用的ID但有个前提就是自增长列的开始ID和该表的最小ID要一致
set @c:=1 select id, @c:=@c+1 as p from tbl_name where @c+1>id order by p desc limit 1第一条记录从1开始 @c+1 = 2 > 1 所以 p =@c +1 = 2 以此类推....... 结果为 id | p | 1 2 2 3 3 4 如果3后面为5 @c+1 = 5 不>5 , order by p desc limit 1 得到 id | p | 3 4 4即为结果
如果能修改表或建立临时表,我倒有一个解决办法~插入一个新field tmpid,用自增长填充select top 1 * from aaa where id<>tmpid order by id id返回tmpid就是最小的未被使用的ID但有个前提就是自增长列的开始ID和该表的最小ID要一致==================================干脆新建一个表x,一个字段id,填入1,2,3.... 直到足够大select min(x.id) from x left join tablename on id where tablename.id is null
{
/*连接到数据库的代码:略*/ $sql="select id form `tablename` order by `id`;
$result=mysql_query($sql);
if($result)
{
$i=1;
while($rs=mysql_fetch_array&&$i<=40000)
{
if($rs['id']==$i) return $i;
$i++;
}
}
return 40001;
}不过这个应该好浪费空间?
function sb()
{
/*连接到数据库的代码:略*/$sql="select id form `tablename` order by `id`;
$result=mysql_query($sql);
if($result)
{
$i=1;
while($rs=mysql_fetch_array&&$i<=40000)
{
if($rs['id']!=$i) return $i;
$i++;
}
}
return 40001;
}把==换成!=。对不起啊,嘻嘻。
----------------------------------------------------------
select min(id)+1 from 表名 t where not exists(select 1 from 表名 where id=a.id+1)
$b=0;
foreach ($a as $c){
$b++;
if ($c != $b){
echo $b ."-";
break;
}
}其实这种思路比多级查询等快的多 Php返回 40000 条字符串都是很快的.
多级查询更是很不明智的:)
不支持子查询,唉
我你的意思是说让我把全部的ID取出来,放到数组里面,然后在循环最多40000次是吗?不知道有没有更好的呢
现在就是暂时先不动数据库了回到主题,这个sql怎么办呢?
foreach ($a as $k=>$v)
{
if($k!=$v-1)
{
echo $a[$k]+1."<br>";//这个就是最小的想要的ID值
break;
}}
比如
a表 id username password ……
b表 id email index ……
两个id 都是自增(通常b不用:)但为了说这事~~咱就用上……).如果操作有误那么a.id b.id有可能不对应.
检测就用这个返回2个的不同id具体位置(当然,语句得再改一改):)是不是有点牵强?乱想的~~仅供参考:)
但是我现在是要解决的是他们之前程序留下的问题我想知道如果数据量较大,怎么写sql好一些:)
我建议还是使用数组循环匹配.不知有什么漂亮的Sql语句~~还等高人指点……
你想找出最小的数据,
你先伸序排列ID
从最小的匹配
------------------------------------------------------
function sb()
{
/*连接到数据库的代码:略*/$sql="select id form `tablename` order by `id` asc
$result=mysql_query($sql);
if($result)
{
$i=1;
while($rs=mysql_fetch_array&&$i<=40000)
{
if($rs['id']!=$i) return $i;
$i++;
}
}
return 40001;
}
set @c:=1
select id, @c:=@c+1 as p from tbl_name where @c+1>id order by p desc limit 1结果中的 p 就是所需结果
declare @t2 table(a int identity(1,1),b int)
declare @i int
set @i=0
while (@i<1000)
begin
insert into @t1
select 1
union
select 2
union
select 3
insert into @t2
select 1
union
select 2
union
select 3
set @i=@i+1
end
delete from @t1 where a<100 and a >60
select top 1 a1.a from @t2 a1 left join @t1 b2 on a1.a=b2.a where b2.b is null纯粹路过,楼主有这意思
set @c:=1
select id, @c:=@c+1 as p from tbl_name where @c+1>id order by p desc limit 1没看懂。
插入一个新field tmpid,先填入连续的整数1,2,3,。。
在该字段上建唯一索引,
然后使用
select min(id) from tablename where id>tmpid 当然插入新字段需要点时间,但是是一次性的,查询时速度会比较快
<?php
/**
* 折半查找未被使用的最小自动增量
* $table 数库的表名
* $id 自动增量的字段名
* $low 查找起点
*/
function binSearch($table,$id,$low=1)
{
//查找当前表中的最大的id
$sql = "select max($id) from $table";
$result = mysql_query($sql);
if ($result)
{
//$low为本次查找起点, $high为本查找终点, $previousHigh上次查找终点
$high = mysql_result($result,0);
$previousHigh = $high;
}
while ($low <= $high)
{
$sql = "select count($id) from $table where $id >= $low and $id <= $high";
$result=mysql_query($sql);
//$rows 为实际返回的记录数
$rows = mysql_result($result,0);
//$records 为理论上的记录数
//当id为自动增量的主键时,$rows必然<=$records
$records = $high - $low + 1;
//$mid 为当前查找段的中间值,分两段查找
$mid = floor( ($low + $high) / 2 );
//实际返回的记录为0,$low就是最小值
if ($rows == 0)
{
break;
}
//实际返回的记录 < 理论的记录, 先从前半段 $low ~ $mid 区间进行查找
else if ($rows < $records)
{
$previousHigh = $high;
$high = $mid;
}
//实际返回的记录 == 理论的记录, 最小id不在前半区,则在后半区找。
else if ($rows == $records)
{
$low = $high + 1;
$high = $previousHigh;
}
}
return $low;
}$conn = @mysql_connect("localhost","root","123456") or die("Can't connect to database");
@mysql_select_db('test',$conn) or die("Can't select database");
echo binSearch('test','id');
?>
看来折半查找还是不错的办法唠叨老大的sql我测试没有成功~查不出值来
select id, @c:=@c+1 as p from tbl_name where @c+1>id order by p desc limit 1第一条记录从1开始
@c+1 = 2 > 1
所以 p =@c +1 = 2
以此类推.......
结果为
id | p |
1 2
2 3
3 4
如果3后面为5 @c+1 = 5 不>5 ,
order by p desc limit 1
得到
id | p |
3 4
4即为结果