请教一下Sql的查询语句

eaqpi 2013-12-20 02:19:51
已知有如下数据库:


日期 单号 ID
2013-1-1 P468899 1
2013-1-2 P654882 4
2013-1-3 P497841 7 求ID
2013-1-3 P648818 10 已获取
2013-1-4 P188618 15 求ID
2013-1-4 P812545 18
2013-1-4 P983115 22
2013-1-5 P840214 28
2013-1-6 P4655552 33

单号为不可重复的单号。
ID 为 自增长主键
排序为 以 日期、单号进行排序


假设 已知 ID 为10 的数据。

求如何取得上一个和下一个经过排序的ID。



...全文
314 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
山寨DBA 2013-12-20
  • 打赏
  • 举报
回复

create table #order(
  order_date date null,
  order_id varchar(100) null,
  ID int null
  )
  
  insert into #order
  select '2013-1-1','P468899','1' union
  select '2013-1-2','P654882','4' union
  select '2013-1-3','P497841','7' union
  select '2013-1-3','P648818','10' union
  select '2013-1-4','P188618','15' union
  select '2013-1-4','P812545','18' union
  select '2013-1-4','P983115','22' union
  select '2013-1-5','P840214','28' union
  select '2013-1-6','P4655552','33'

 select * from #order where ID in(
 select top 1 ID from #order where ID>10 order by ID desc 
 union select top 1 ID from #order where ID<10 order by ID
 ) 
eaqpi 2013-12-20
  • 打赏
  • 举报
回复
收工,使用Top 得使用2次查询。 大家辛苦了,各给福利 http://www.huakoo.net/bbs/forum.php?mod=viewthread&tid=172613
山寨DBA 2013-12-20
  • 打赏
  • 举报
回复
如果你用top 的话,就加上order by吧,也可以实现的。我给你的那个就是那样的。 不过看来看去,如果数据量很大的话,楼主的方法最给力了。
發糞塗牆 2013-12-20
  • 打赏
  • 举报
回复
top 1如果没有order by是很随机的....
eaqpi 2013-12-20
  • 打赏
  • 举报
回复
使用 Top(1) 出来的数据 完全不知道是那一条啊。和上下条无关有没有啊!
山寨DBA 2013-12-20
  • 打赏
  • 举报
回复
我晕啊,我写好代码就变成19楼了。。。。这速度也忒神速了。。。 楼主果断大神啊
山寨DBA 2013-12-20
  • 打赏
  • 举报
回复
create table #order( order_date date null, order_id varchar(100) null, ID int null ) insert into #order select '2013-1-1','P468899','1' union select '2013-1-2','P654882','4' union select '2013-1-3','P497841','7' union select '2013-1-3','P648818','10' union select '2013-1-4','P188618','15' union select '2013-1-4','P812545','18' union select '2013-1-4','P983115','22' union select '2013-1-5','P840214','28' union select '2013-1-6','P4655552','33' select * from #order where ID in( select top 1 ID from #order where ID>10 order by ID desc union select top 1 ID from #order where ID<10 order by ID )
KeepSayingNo 2013-12-20
  • 打赏
  • 举报
回复
下面是查询的结果

如果楼主要查询任意ID的,可以将10改成变量,然后用动态SQL就可以了
eaqpi 2013-12-20
  • 打赏
  • 举报
回复
版主的方法是可以的,其他人的方法都有问题。 (select Max(id) id from tb t2 where t1.日期 >= t2.日期 and t1.单号 > t2.单号)t2 这个 使用max(ID)和min(ID)出来的数据应该会出错 select 10 id, (select min(id) from #t where id>10) nextid ,(select max(id) from #t where id<10) preid 如果能以ID排序的话,就要容易一些,ID 基本上都是乱序的,隔天补单,隔周补单很正常啊。 版主使用的重新建立rownum的方法,但是我在切换单据或者查找单据的时候,这个用的很频繁。 【前一条】这个东西会有人不停的点,(他们自己也不知道单据是否被输入了,或者就几天的事情,懒的用查询。 不知道还有没有更有效率的方法。 多建立个字段,使用 时间+ 单号(20131212P1555475)的连接字符作为 数据,然后建立索引查询? 还是得使用order by 啊。
KeepSayingNo 2013-12-20
  • 打赏
  • 举报
回复
考虑到你的ID是自增长键,充分利用这个条件,没必要再用row_number()函数去排序了,楼主可以看看我写的,大数量应该也没问题。

select * from (select top 1 * from tb where ID<10 order by ID DESC) tt
union all
select top 1 * from tb where ID>10 
Leon_He2014 2013-12-20
  • 打赏
  • 举报
回复

select '2013-1-1' 日期,	'P468899' 单号,	   1 ID	into #t union all
select '2013-1-2',	'P654882',	   4	union all	
select '2013-1-3',	'P497841',	   7	union all	
select '2013-1-3',	'P648818',    10	union all	
select '2013-1-4',	'P188618',	   15	union all	
select '2013-1-4',	'P812545',	   18	union all	
select '2013-1-4',	'P983115',	   22	union all	
select '2013-1-5',	'P840214',	   28	union all	
select '2013-1-6',	'P4655552',   33

select a.*,t.nextid,t.preid
from
#t a
join 
(
select 10 id, (select min(id) from #t where id>10) nextid ,(select max(id) from #t where id<10) preid
) t
on a.ID=t.id
再修改了一下
熊猫王子 2013-12-20
  • 打赏
  • 举报
回复
楼主都说清楚了排序以日期、单号进行排序,你们还拿id排序
  • 打赏
  • 举报
回复
引用 7 楼 eaqpi 的回复:
我的目的只是返回一条数据,而不是要返回10万条数据。是在10万条数据中查找。 取得该条数据的上一条或者下一条。 数据是根据 日期和单号进行排序的。ID号有可能乱的,跳度也有可以很大,比如在几个月后补单据的时候。 日期和单号用的是发生日的,ID号应该是新生成的。 本来想 "SELECT TOP(2) FORM TB WHERE 日期>= '" & _日期 & " AND 单号>='" & 单号 &"'" 后来发现 Top 有时候出来的数据不对...
哦,那就改一下,这么写就效率高多了:

create table tb(日期	   datetime,     单号 varchar(20),	   ID	 int)

insert into tb
select '2013-1-1',	'P468899',	   1	union all
select '2013-1-2',	'P654882',	   4	union all	
select '2013-1-3',	'P497841',	   7	union all	
select '2013-1-3',	'P648818',    10	union all	
select '2013-1-4',	'P688618',	   15	union all	--改了一下单号
select '2013-1-4',	'P812545',	   18	union all	
select '2013-1-4',	'P983115',	   22	union all	
select '2013-1-5',	'P840214',	   28	union all	
select '2013-1-6',	'P4655552',   33
go




select t1.日期,t1.单号,t1.id,
       t2.id as prev_id,
       t3.id as next_id
from tb t1
outer apply (select Max(id) id from tb t2 where t1.日期 >= t2.日期 and t1.单号 > t2.单号)t2
outer apply (select min(id) id from tb t3 where t3.日期 >= t1.日期 and t3.单号 > t1.单号)t3

where t1.id = 10
/*
日期	单号	id	prev_id	next_id
2013-01-03 00:00:00.000	P648818	10	7	18
*/
Leon_He2014 2013-12-20
  • 打赏
  • 举报
回复

select '2013-1-1' 日期,	'P468899' 单号,	   1 ID	into #t union all
select '2013-1-2',	'P654882',	   4	union all	
select '2013-1-3',	'P497841',	   7	union all	
select '2013-1-3',	'P648818',    10	union all	
select '2013-1-4',	'P188618',	   15	union all	
select '2013-1-4',	'P812545',	   18	union all	
select '2013-1-4',	'P983115',	   22	union all	
select '2013-1-5',	'P840214',	   28	union all	
select '2013-1-6',	'P4655552',   33

select *
from
(
select 10 id, (select min(id) from #t where id>10) nextid ,(select max(id) from #t where id<10) preid
) t
id为自增长主键的话,可以走索引,应该挺快的
熊猫王子 2013-12-20
  • 打赏
  • 举报
回复
create table tb(日期 datetime, 单号 varchar(20), ID int) insert into tb select '2013-1-1', 'P468899', 1 union all select '2013-1-2', 'P654882', 4 union all select '2013-1-3', 'P497841', 7 union all select '2013-1-3', 'P648818', 10 union all select '2013-1-4', 'P188618', 15 union all select '2013-1-4', 'P812545', 18 union all select '2013-1-4', 'P983115', 22 union all select '2013-1-5', 'P840214', 28 union all select '2013-1-6', 'P4655552', 33 go select t1.日期,t1.单号,t1.id, t2.id, t3.id from (select *, ROW_NUMBER() over(order by 日期,单号) as rownum from tb) t1 left join (select *, ROW_NUMBER() over(order by 日期,单号) as rownum from tb) t2 on t1.rownum = t2.rownum + 1 left join (select *, ROW_NUMBER() over(order by 日期,单号) as rownum from tb) t3 on t1.rownum = t3.rownum - 1 where t1.id = 10
發糞塗牆 2013-12-20
  • 打赏
  • 举报
回复
引用 7 楼 eaqpi 的回复:
我的目的只是返回一条数据,而不是要返回10万条数据。是在10万条数据中查找。 取得该条数据的上一条或者下一条。 数据是根据 日期和单号进行排序的。ID号有可能乱的,跳度也有可以很大,比如在几个月后补单据的时候。 日期和单号用的是发生日的,ID号应该是新生成的。 本来想 "SELECT TOP(2) FORM TB WHERE 日期>= '" & _日期 & " AND 单号>='" & 单号 &"'" 后来发现 Top 有时候出来的数据不对...
你这个语句应该是top 3吧?
發糞塗牆 2013-12-20
  • 打赏
  • 举报
回复
所以要加个排序列,如果where条件高效,速度完全没问题
eaqpi 2013-12-20
  • 打赏
  • 举报
回复
上面 语句漏了 order by
eaqpi 2013-12-20
  • 打赏
  • 举报
回复
我的目的只是返回一条数据,而不是要返回10万条数据。是在10万条数据中查找。 取得该条数据的上一条或者下一条。 数据是根据 日期和单号进行排序的。ID号有可能乱的,跳度也有可以很大,比如在几个月后补单据的时候。 日期和单号用的是发生日的,ID号应该是新生成的。 本来想 "SELECT TOP(2) FORM TB WHERE 日期>= '" & _日期 & " AND 单号>='" & 单号 &"'" 后来发现 Top 有时候出来的数据不对...
  • 打赏
  • 举报
回复
引用 3 楼 eaqpi 的回复:
如果数据很多,10来万条,这个语句对系统的负担大吗? select *, ROW_NUMBER() over(order by id) as rownum from tb 相当于建立了一个重新排序过的虚拟的表了吧。
嗯,不过10万条数据,这个量很小,应该是没什么影响的
加载更多回复(5)

34,576

社区成员

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

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