首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

100分-怎么剔除不合规律的行

2012-02-27 
100分--如何剔除不合规律的行?表结构如下:onlineusertime0f1t11f1t20f2t31f2t40f1t50f1t61f1t71f2t80f2t91

100分--如何剔除不合规律的行?
表结构如下:
online         user         time
      0               f1             t1
      1               f1             t2
      0               f2             t3
      1               f2             t4
      0               f1             t5
      0               f1             t6
      1               f1             t7
      1               f2             t8
      0               f2             t9
      1               f2             t10
      1               f3             t11
      0               f3             t12
      1f1t13
      1f4t14
      1f4t15
      0f4t16
      1           f4t17

说明:表按时间顺序排列,online中0表示上线,1表示下线,time是时间字段。对每个user,正常情况下是先记录上线后记录下线,表中有坏数据是只记录了上线而没有记录下线,或只记录了下线而没有上线。
现在的问题是如何选出正确的上线下线记录(不能删除原表数据)?
如上表,正确选择结果应为:

      0               f1             t1
      1               f1             t2
      0               f2             t3
      1               f2             t4
      0               f1             t6
      1               f1             t7
      0               f2             t9
      1               f2             t10
      0f4t16
      1           f4t17



[解决办法]
--f3两条数据因为按1,0排列,所以是坏记录
declare @t table (online int,[user] varchar(10),time varchar(10))
insert @t select 0, 'f1 ', 't01 '
union all select 1, 'f1 ', 't02 '
union all select 0, 'f2 ', 't03 '
union all select 1, 'f2 ', 't04 '
union all select 0, 'f1 ', 't05 '
union all select 0, 'f1 ', 't06 '


union all select 1, 'f1 ', 't07 '
union all select 1, 'f2 ', 't08 '
union all select 0, 'f2 ', 't09 '
union all select 1, 'f2 ' , 't10 '
union all select 1, 'f3 ', 't11 '
union all select 0, 'f3 ' , 't12 '
union all select 1, 'f1 ', 't13 '
union all select 1, 'f4 ' , 't14 '
union all select 1, 'f4 ', 't15 '
union all select 0, 'f4 ' , 't16 '
union all select 1, 'f4 ' , 't17 '

select * from @t a
where (
online=0
and (select top 1 online
from @t
where [user]=a.[user]
and time> a.time
order by time
) <> 0
)
or
(
online=1
and (select top 1 online
from @t
where [user]=a.[user]
and time <a.time
order by time desc
) <> 1
)

/*
onlineusertime
----------------------------
0f1t01
1f1t02
0f2t03
1f2t04
0f1t06
1f1t07
0f2t09
1f2t10
0f4t16
1f4t17
*/


[解决办法]
create table ta(online int, [user] varchar(2) , time varchar(5))
insert ta select 0, 'f1 ', 't1 '
union all select 1, 'f1 ', 't2 '
union all select 0, 'f2 ', 't3 '
union all select 1, 'f2 ', 't4 '
union all select 0, 'f1 ', 't5 '
union all select 0, 'f1 ', 't6 '
union all select 1, 'f1 ', 't7 '
union all select 1, 'f2 ', 't8 '
union all select 0, 'f2 ', 't9 '
union all select 1, 'f2 ', 't10 '
union all select 1, 'f3 ', 't11 '
union all select 0, 'f3 ', 't12 '
union all select 1, 'f1 ', 't13 '
union all select 1, 'f4 ', 't14 '
union all select 1, 'f4 ', 't15 '
union all select 0, 'f4 ', 't16 '
union all select 1, 'f4 ', 't17 '


查询:
select * from ta a
where not --如果只是查询这样样加not
exists(select 1 from ta b where time=(select min(time) from ta where time> a.time)
and (online=a.online or online <a.online) and [user]=a.[user])


结果为:
/*
online user time
----------- ---- -----
0 f1 t1
1 f1 t2
0 f2 t3
1 f2 t4
0 f1 t6
1 f1 t7
0 f2 t9
1 f2 t10
0 f3 t12
1 f1 t13
0 f4 t16
1 f4 t17

(所影响的行数为 12 行)
*/

热点排行