select a.a+1 as the_begin, (select min(a)-1 from test1 where a>a.a+1) the_end from test1 a left join test1 b on a.a+1=b.a where b.a is null and a.a+1<>(select max(a)+1 from test1) the_begin the_end ----------- ----------- 3 9 11 999(所影响的行数为 2 行)
select a.a+1 as the_begin, (select min(a)-1 from test1 where a>a.a+1) the_end from test1 a left join test1 b on a.a+1=b.a where b.a is null and a.a+1<>(select max(a)+1 from test1) union select 1,(select min(a)-1 from test1 where a>1) from test1 where (select min(a) from test1)<>1
有没有答案了??我这里有一个:insert test1 select c from ( select t1.b+t2.b*10+t3.b*100+t4.b*1000 as c from ( select 0 as b union all select 1 as b union all select 2 as b union all select 3 as b union all select 4 as b union all select 5 as b union all select 6 as b union all select 7 as b union all select 8 as b union all select 9 as b ) as t1, ( select 0 as b union all select 1 as b union all select 2 as b union all select 3 as b union all select 4 as b union all select 5 as b union all select 6 as b union all select 7 as b union all select 8 as b union all select 9 as b ) as t2, ( select 0 as b union all select 1 as b union all select 2 as b union all select 3 as b union all select 4 as b union all select 5 as b union all select 6 as b union all select 7 as b union all select 8 as b union all select 9 as b ) as t3, ( select 0 as b union all select 1 as b union all select 2 as b union all select 3 as b union all select 4 as b union all select 5 as b union all select 6 as b union all select 7 as b union all select 8 as b union all select 9 as b ) as t4 ) as t5 where c<>0 and c not in (select a from test1)
不过按铁诺的条件,够用了,从那个贴学一招: select * from (select rownum a from all_objects) where a > (select min(a) from test1) and a < (select max(a) from test1) and a not in (select a from test1);
all_objects算不算是附加的数据库对象?
没想到今天来了后居然有这么多条回复,我本以为只有十来条的。 谢谢大家的关注!在PL/SQL中好处理是因为Oracle中有rownum的存在。 但是如果是一个新的DB的话,用系统表all_objects来处理是不合适的。 因为all_objects中间的纪录数有可能不够,而用ALL_TAB_COLUMNS这个系统表在任何情况下都不要担心数据不够的问题。因此我用PL/SQL处理这个问题的方法是: select a.r from (select rownum r from ALL_TAB_COLUMNS where rownum < 10000) a,test1 b where a.r=b.a(+) and a.r <=(select max(a) from test1) and b.a is null; 这条语句非常的快,1秒中都不要就可以出来正确的结果。但是在T-SQL中,我只能想出一条比较笨的语句,这条语句要执行1分钟才能有正确的结果: select a.r from (select (select count(*) from master.dbo.sysmessages bb where bb.description < aa.description) + 1 r from master.dbo.sysmessages aa ) a left outer join test1 b on a.r = b.a where a.r <=(select max(a) from test1) and b.a is null order by a.r欢迎大家能想出更好的方法。
海兄的语句如果想在PL/SQL中用,那么必须改成下面的形式:select c from ( select t1.b+t2.b*10+t3.b*100+t4.b*1000 c from ( select 0 b from dual union all select 1 b from dual union all select 2 b from dual union all select 3 b from dual union all select 4 b from dual union all select 5 b from dual union all select 6 b from dual union all select 7 b from dual union all select 8 b from dual union all select 9 b from dual ) t1, ( select 0 b from dual union all select 1 b from dual union all select 2 b from dual union all select 3 b from dual union all select 4 b from dual union all select 5 b from dual union all select 6 b from dual union all select 7 b from dual union all select 8 b from dual union all select 9 b from dual ) t2, ( select 0 b from dual union all select 1 b from dual union all select 2 b from dual union all select 3 b from dual union all select 4 b from dual union all select 5 b from dual union all select 6 b from dual union all select 7 b from dual union all select 8 b from dual union all select 9 b from dual ) t3, ( select 0 b from dual union all select 1 b from dual union all select 2 b from dual union all select 3 b from dual union all select 4 b from dual union all select 5 b from dual union all select 6 b from dual union all select 7 b from dual union all select 8 b from dual union all select 9 b from dual ) t4 ) t5 where c < >0 and c not in (select a from test1) and c <(select max(a) from test1) order by c;不过这条语句在Oracle中要花去1202ms 我的那条PL/SQL语句要花去230ms 按钮JJ的那条语句则要花去120ms
Yang_的改成LEFT JOIN 可能要快点
铁斑竹:not in 改成LEFT JOIN 再试一下
Yang_的语句在PL/SQL中改成外连接形式: select c from ( select t1.b+t2.b*10+t3.b*100+t4.b*1000 c from ( select 0 b from dual union all select 1 b from dual union all select 2 b from dual union all select 3 b from dual union all select 4 b from dual union all select 5 b from dual union all select 6 b from dual union all select 7 b from dual union all select 8 b from dual union all select 9 b from dual ) t1, ( select 0 b from dual union all select 1 b from dual union all select 2 b from dual union all select 3 b from dual union all select 4 b from dual union all select 5 b from dual union all select 6 b from dual union all select 7 b from dual union all select 8 b from dual union all select 9 b from dual ) t2, ( select 0 b from dual union all select 1 b from dual union all select 2 b from dual union all select 3 b from dual union all select 4 b from dual union all select 5 b from dual union all select 6 b from dual union all select 7 b from dual union all select 8 b from dual union all select 9 b from dual ) t3, ( select 0 b from dual union all select 1 b from dual union all select 2 b from dual union all select 3 b from dual union all select 4 b from dual union all select 5 b from dual union all select 6 b from dual union all select 7 b from dual union all select 8 b from dual union all select 9 b from dual ) t4 ) t5 ,test1 where c <>0 and c=test1.a(+) and test1.a is null and c <(select max(a) from test1) order by c;执行时间为821ms,确实要快1/3。 但是由于数据量不大,效果不明显。
查阅出max(a)和min(a),然后在(min(a),max(a))这个范围内比较数据表中的数据。但是SQL比较难写,先探讨方法是否可行。
就像这个问题不是我想出来的,但是我在一个地方看到。
就想将其解决,但是现在还没想到好方法。你说这个问题不实际,但我告诉你现实生活中有可能遇到。
而大部分人遇到后一定是会用光标去解决的。
用PL/SQL怎么写?
(select min(a)-1 from test1 where a>a.a+1) the_end
from test1 a left join test1 b on a.a+1=b.a
where b.a is null and a.a+1<>(select max(a)+1 from test1)
the_begin the_end
----------- -----------
3 9
11 999(所影响的行数为 2 行)
select a.a+1 as the_begin,
(select min(a)-1 from test1 where a>a.a+1) the_end
from test1 a left join test1 b on a.a+1=b.a
where b.a is null and a.a+1<>(select max(a)+1 from test1)
union
select 1,(select min(a)-1 from test1 where a>1)
from test1
where (select min(a) from test1)<>1
select c from
(
select t1.b+t2.b*10+t3.b*100+t4.b*1000 as c
from
(
select 0 as b
union all
select 1 as b
union all
select 2 as b
union all
select 3 as b
union all
select 4 as b
union all
select 5 as b
union all
select 6 as b
union all
select 7 as b
union all
select 8 as b
union all
select 9 as b
) as t1,
(
select 0 as b
union all
select 1 as b
union all
select 2 as b
union all
select 3 as b
union all
select 4 as b
union all
select 5 as b
union all
select 6 as b
union all
select 7 as b
union all
select 8 as b
union all
select 9 as b
) as t2,
(
select 0 as b
union all
select 1 as b
union all
select 2 as b
union all
select 3 as b
union all
select 4 as b
union all
select 5 as b
union all
select 6 as b
union all
select 7 as b
union all
select 8 as b
union all
select 9 as b
) as t3,
(
select 0 as b
union all
select 1 as b
union all
select 2 as b
union all
select 3 as b
union all
select 4 as b
union all
select 5 as b
union all
select 6 as b
union all
select 7 as b
union all
select 8 as b
union all
select 9 as b
) as t4
) as t5
where c<>0
and c not in (select a from test1)
x_zou在那里说了一个贴好,但是打不开!
这个,有谁知道怎么打开这样的贴子吗?
.....
where c<>0
and c not in (select a from test1) and c <(select max(a) from test1)
order by c
N_chow(一剑飘香++) : 没错!
不过当时只是求断号的最小值,但要按铁兄的规则在sql里是没法实现的,
oracle里有sequence的概念,所以很容易一句sql搞定。
还有可以用left join.
sequence也是要创建才行的啊。
select * from
(select rownum a from all_objects)
where a > (select min(a) from test1)
and a < (select max(a) from test1)
and a not in (select a from test1);
谢谢大家的关注!在PL/SQL中好处理是因为Oracle中有rownum的存在。
但是如果是一个新的DB的话,用系统表all_objects来处理是不合适的。
因为all_objects中间的纪录数有可能不够,而用ALL_TAB_COLUMNS这个系统表在任何情况下都不要担心数据不够的问题。因此我用PL/SQL处理这个问题的方法是:
select a.r from
(select rownum r from ALL_TAB_COLUMNS where rownum < 10000) a,test1 b
where a.r=b.a(+) and a.r <=(select max(a) from test1) and b.a is null;
这条语句非常的快,1秒中都不要就可以出来正确的结果。但是在T-SQL中,我只能想出一条比较笨的语句,这条语句要执行1分钟才能有正确的结果:
select a.r from
(select (select count(*) from master.dbo.sysmessages bb where bb.description < aa.description) + 1 r
from master.dbo.sysmessages aa ) a left outer join test1 b on a.r = b.a
where a.r <=(select max(a) from test1) and b.a is null order by a.r欢迎大家能想出更好的方法。
2.也是速度
还是Yang_那种速度快,且通用,也不会比PL/SQL的慢
海兄的方法确实好,而且没有用到其它的数据库对象。
并且效率高,虽比PL/SQL的慢些,但也只要1秒多钟。j9988说的确实不错。
最关键的是如果sysmessages没有修改过,那么纪录只有7564,不够9999
(
select t1.b+t2.b*10+t3.b*100+t4.b*1000 c
from
(
select 0 b from dual
union all
select 1 b from dual
union all
select 2 b from dual
union all
select 3 b from dual
union all
select 4 b from dual
union all
select 5 b from dual
union all
select 6 b from dual
union all
select 7 b from dual
union all
select 8 b from dual
union all
select 9 b from dual
) t1,
(
select 0 b from dual
union all
select 1 b from dual
union all
select 2 b from dual
union all
select 3 b from dual
union all
select 4 b from dual
union all
select 5 b from dual
union all
select 6 b from dual
union all
select 7 b from dual
union all
select 8 b from dual
union all
select 9 b from dual
) t2,
(
select 0 b from dual
union all
select 1 b from dual
union all
select 2 b from dual
union all
select 3 b from dual
union all
select 4 b from dual
union all
select 5 b from dual
union all
select 6 b from dual
union all
select 7 b from dual
union all
select 8 b from dual
union all
select 9 b from dual
) t3,
(
select 0 b from dual
union all
select 1 b from dual
union all
select 2 b from dual
union all
select 3 b from dual
union all
select 4 b from dual
union all
select 5 b from dual
union all
select 6 b from dual
union all
select 7 b from dual
union all
select 8 b from dual
union all
select 9 b from dual
) t4
) t5
where c < >0
and c not in (select a from test1) and c <(select max(a) from test1)
order by c;不过这条语句在Oracle中要花去1202ms
我的那条PL/SQL语句要花去230ms
按钮JJ的那条语句则要花去120ms
select c from
(
select t1.b+t2.b*10+t3.b*100+t4.b*1000 c
from
(
select 0 b from dual
union all
select 1 b from dual
union all
select 2 b from dual
union all
select 3 b from dual
union all
select 4 b from dual
union all
select 5 b from dual
union all
select 6 b from dual
union all
select 7 b from dual
union all
select 8 b from dual
union all
select 9 b from dual
) t1,
(
select 0 b from dual
union all
select 1 b from dual
union all
select 2 b from dual
union all
select 3 b from dual
union all
select 4 b from dual
union all
select 5 b from dual
union all
select 6 b from dual
union all
select 7 b from dual
union all
select 8 b from dual
union all
select 9 b from dual
) t2,
(
select 0 b from dual
union all
select 1 b from dual
union all
select 2 b from dual
union all
select 3 b from dual
union all
select 4 b from dual
union all
select 5 b from dual
union all
select 6 b from dual
union all
select 7 b from dual
union all
select 8 b from dual
union all
select 9 b from dual
) t3,
(
select 0 b from dual
union all
select 1 b from dual
union all
select 2 b from dual
union all
select 3 b from dual
union all
select 4 b from dual
union all
select 5 b from dual
union all
select 6 b from dual
union all
select 7 b from dual
union all
select 8 b from dual
union all
select 9 b from dual
) t4
) t5 ,test1
where c <>0
and c=test1.a(+) and test1.a is null
and c <(select max(a) from test1)
order by c;执行时间为821ms,确实要快1/3。
但是由于数据量不大,效果不明显。
那就有几亿了.
关联两次就比较够呛了。
关联三次还得了?