导航
  • 主页
  • 基础类
  • 应用实例
  • 新技术前沿

求SQL文

painAndhappy 2004-10-07 10:49:57
怎样取得和最后一行一致的,且连续相同的最前面的数据?

如:
数值 时间
-------------------
100 2001/10/1 ----------------1
105 2001/10/1 ----------------2
100 2001/10/2 ----------------3
105 2001/10/3 ----------------4
105 2001/10/4 ----------------5
105 2001/10/4 ----------------6
-------------------

最后一行是编号为6的105
所以要取的是编号为4的105
...全文
174 点赞 收藏 12
写回复
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
painAndhappy 2004-10-07
大哥,查询条件只能用数值.时间并不一定是"时间=@时间-1".
如果编号为4的数据变成
105 2001/10/4 ----------------4
之类的,就不能得出这条数据了.
所以上面例子中的时间,实际上不用去看它.:D


数据如下:

数值
-------------------
100 ----------------1
105 ----------------2
100 ----------------3
105 ----------------4
105 ----------------5
105 ----------------6
-------------------

也就是要取得和最后一行数值一致的,且从最后一行往前看,数值一直相同的最前面的那个数值.

见数据:最后一行是编号为6的数据,数值为105
(1)往前看,是编号为5的数据,数值为105,和最后一行相同
(2)再往前看,是编号为4的数据,数值为105,和编号为5的数据的数值相同
(3)继续往前看,是编号为3的数据,数值为100,和编号为4的数据的数值"不"相同
所以,"连续"的和最后一行数据相同的,最先出现的一个编号为4的数据,因此就取编号为4的数据.
(虽然编号为2的数据的数值和最后一行的相同,但由于中间有编号为3的数据和最后一行不相等,所以也就不连续了.)
另外,如果最后一行的数据和最后第二行的数据不相等,那就取最后一行的.

不知道这样说清楚了没有:)
请帮我再想想.
回复
Selectau_fname 2004-10-07
强!~~~~~~~~
回复
--示例

--示例数据
declare @t table(数值 int,时间 datetime)
insert @t select 100,'2001/10/1'
union all select 105,'2001/10/1'
union all select 100,'2001/10/2'
union all select 105,'2001/10/3'
union all select 105,'2001/10/4'
union all select 105,'2001/10/4'

--查询
declare @数值 int,@时间 datetime
select @数值=数值,@时间=时间 from @t
select * from @t where 数值=@数值 and 时间=@时间-1

/*--查询结果

数值 时间
----------- ---------------------------
105 2001-10-03 00:00:00.000

(所影响的行数为 1 行)
--*/
回复
Selectau_fname 2004-10-07
楼主能说清楚点吗?
回复
painAndhappy 2004-10-07
谢谢邹大哥,基本思路明白了,剩下的一些小问题应该能够自己搞定.
今天幸亏你帮忙,要不然交不出活可就惨了 :D
回复
--假设你的表中已经有 编号 这个主键字段,可以这样处理

--示例数据
create table tb(编号 int identity,数值 int,时间 datetime)
insert tb select 100,'2001/10/1'
union all select 105,'2001/10/1'
union all select 100,'2001/10/2'
union all select 105,'2001/10/3'
union all select 105,'2001/10/4'
union all select 105,'2001/10/4'
go

--查询
select * from tb
where 编号>(
select max(编号) from tb
where 数值<>(select top 1 数值 from tb order by 时间 desc))
go

--删除测试
drop table tb

/*--测试结果

编号 数值 时间
----------- ----------- ---------------------------
4 105 2001-10-03 00:00:00.000
5 105 2001-10-04 00:00:00.000
6 105 2001-10-04 00:00:00.000

(所影响的行数为 3 行)

--*/
回复
painAndhappy 2004-10-07
原表不是我定的,这边所作的开发只是总体的一部分. :(
现在先抛开效率,只要能做出来就可以.SQL以后再优化,或者进行数据库变更.
回复
那你还是在原表加主键(或者自增字段吧),60多万记录放到临时表中去加主键,效率之低,可想而知.
回复
painAndhappy 2004-10-07
这是一个记LOG的表,没有主键的. :(
不过,整个处理是放在存储过程中实现,所以,如果确实需要主键定位的话,可以自己定义一个零时表,放一个自增长字段,用它来作为主键定位.(数据比较多,现在测试的就有60多万条).

如下:
编号 数值 时间
-------------------
1 100 2001/10/1 ----------------1
2 105 2001/10/1 ----------------2
3 100 2001/10/2 ----------------3
4 105 2001/10/3 ----------------4
5 105 2001/10/4 ----------------5
6 105 2001/10/4 ----------------6
-------------------

但是有了主键,下一步又应该怎么处理呢?
回复
要主键(唯一键),能定位记录才行.
回复
painAndhappy 2004-10-07
那还是加上时间吧.
不过时间只是用来排序,只确定行的顺序,如:order by 时间
或者
select * from t where 时间 = (select max(时间) from t)来取得最后行的数据.
因为时间是不定的,所以不能用{时间=某个具体数值}来作为抽出条件.

这样的话,能写SQL文了吗?
回复
SQL中没有记录号,也没有行序的概念,所以必须加辅助字段
回复
发动态
发帖子
MS-SQL Server
创建于2007-09-28

3.2w+

社区成员

MS-SQL Server相关内容讨论专区
申请成为版主
社区公告
暂无公告