高难度SQL查询。。。解决的多送分。。

fanhui1022 2009-02-07 08:24:40
现在有一个表A,字段如下:
id date times
10 2009-01-01 3
11 2009-01-02 0
12 2009-01-03 0
13 2009-01-04 0
14 2009-01-05 2
15 2009-01-06 0
16 2009-01-07 0
17 2009-01-08 0
18 2009-01-09 0
19 2009-01-10 0
20 2009-01-05 6
21 2009-01-06 0
22 2009-01-07 0
23 2009-01-08 0
24 2009-01-09 0
25 2009-01-10 0
26 2009-01-09 0
27 2009-01-09 0
要实现的是过滤连续5条或5条以上times字段为0的数据
过滤后的结果集如下:
id date times
10 2009-01-01 3
11 2009-01-02 0
12 2009-01-03 0
13 2009-01-04 0
14 2009-01-05 2
20 2009-01-05 6
数据量比较大,有2000多万,所以不希望用太多条嵌套的SQL语句。问题解决了我把所有的分都给您。非常感谢!
...全文
153 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
fanhui1022 2009-02-09
  • 打赏
  • 举报
回复
问题已解决。结贴了~感谢各位!
SQL> SELECT * FROM A;

ID SJ TIMES
--------------------------------------- ----------- ---------------------------------------
10 2009-1-1 3
11 2009-1-2 0
12 2009-1-3 0
13 2009-1-4 0
14 2009-1-5 2
15 2009-1-6 0
16 2009-1-7 0
17 2009-1-8 0
18 2009-1-9 0
19 2009-1-10 0
20 2009-1-5 6
21 2009-1-6 0
22 2009-1-7 0
23 2009-1-8 0
24 2009-1-9 0
25 2009-1-10 0
26 2009-1-9 0
27 2009-1-9 0
28 2009-1-9 1

19 rows selected

SQL>
SQL> SELECT ID, SJ, TIMES
2 FROM (SELECT t.ID,
3 t.SJ,
4 t.TIMES,
5 COUNT(1) OVER(PARTITION BY ZS) C,
6 ROW_NUMBER() OVER(PARTITION BY ZS ORDER BY ROWNUM) RID
7 FROM (SELECT A.*, SUM(TIMES) OVER(ORDER BY ID) ZS FROM A) t)
8 WHERE C < 6 or (C >= 6 AND RID = 1)
9 /

ID SJ TIMES
--------------------------------------- ----------- ---------------------------------------
10 2009-1-1 3
11 2009-1-2 0
12 2009-1-3 0
13 2009-1-4 0
14 2009-1-5 2
20 2009-1-5 6
28 2009-1-9 1

7 rows selected

SQL>
DengXingJie 2009-02-08
  • 打赏
  • 举报
回复
顶一下
fanhui1022 2009-02-08
  • 打赏
  • 举报
回复
wangxin6302:
  非常感谢,使用游标不失为一种解决办法。期待更好的解决办法,如果没有更好的办法就使用这个办法了。分少不了你的- -。
allanic:
  您写出的SQL语句实现不了这个功能,另外ID也不是连续的。

数据库使用的是oracle,oracle里面不知道有没有能实现该功能的函数。
zoutuo 2009-02-08
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 wangxin6302 的回复:]
我用游标实现的

A表结构及数据

id date times
1 2009-2-7 21:17:06 0
2 2009-2-7 21:17:38 2
3 2009-2-7 21:17:39 0
4 2009-2-7 21:17:46 3
5 2009-2-7 21:17:47 1
6 2009-2-7 21:17:48 0
7 2009-2-7 21:17:49 0
8 2009-2-7 21:17:50 0
9 2009-2-7 21:17:50 0
10 2009-2-7 21:17:51 0
11 2009-2-7 21:17:52 0
12 2009-2-7 21:17:53 0
13 2009-2-7 21:17:55 5
14 2009-2-7 21:17:56 6
15 2…
[/Quote]
高手!
wangxin6302 2009-02-07
  • 打赏
  • 举报
回复
接分喽~~呵呵 不知道 数据要是很多的话 性能怎么样

二楼那个我试了 不好用啊~~~
wangxin6302 2009-02-07
  • 打赏
  • 举报
回复
我用游标实现的

A表结构及数据

id date times
1 2009-2-7 21:17:06 0
2 2009-2-7 21:17:38 2
3 2009-2-7 21:17:39 0
4 2009-2-7 21:17:46 3
5 2009-2-7 21:17:47 1
6 2009-2-7 21:17:48 0
7 2009-2-7 21:17:49 0
8 2009-2-7 21:17:50 0
9 2009-2-7 21:17:50 0
10 2009-2-7 21:17:51 0
11 2009-2-7 21:17:52 0
12 2009-2-7 21:17:53 0
13 2009-2-7 21:17:55 5
14 2009-2-7 21:17:56 6
15 2009-2-7 21:17:58 0
16 2009-2-7 21:18:00 0
17 2009-2-7 21:18:02 0
18 2009-2-7 21:18:05 0


输出表结果
id date times
1 2009-02-07 21:17:05.827 0
2 2009-02-07 21:17:37.780 2
3 2009-02-07 21:17:38.827 0
4 2009-02-07 21:17:45.750 3
5 2009-02-07 21:17:46.950 1
13 2009-02-07 21:17:54.623 5
14 2009-02-07 21:17:55.560 6
15 2009-02-07 21:17:58.187 0
16 2009-02-07 21:17:59.750 0
17 2009-02-07 21:18:02.153 0
18 2009-02-07 21:18:04.670 0

--游标开始
declare @temp_nu int

set @temp_nu=0

declare @id_t int
declare @date_t datetime
declare @times_t int

create table #lin
(
id int,
date datetime,
times int
)

create table #lin_out
(
id int,
date datetime,
times int
)


DECLARE zd CURSOR SCROLL
FOR

select id, date, times from dbo.A

OPEN zd

FETCH RELATIVE 1 FROM zd into @id_t,@date_t,@times_t

WHILE @@FETCH_STATUS = 0
BEGIN
--执行代码部分开始




if @times_t=0
begin
set @temp_nu=@temp_nu+1
insert into #lin(id, date, times) values(@id_t,@date_t,@times_t)
end



if @times_t!=0
begin
if @temp_nu<5
begin
insert into #lin_out(id, date, times)
select id, date, times from #lin
end
set @temp_nu=0
delete from #lin

insert into #lin_out(id, date, times) values(@id_t,@date_t,@times_t)

end




--执行代码部分结束
FETCH RELATIVE 1 FROM zd into @id_t,@date_t,@times_t
END

CLOSE zd

DEALLOCATE zd

if @temp_nu<5
begin
insert into #lin_out(id, date, times)
select id, date, times from #lin
end

select * from #lin_out
drop table #lin
drop table #lin_out
wangxin6302 2009-02-07
  • 打赏
  • 举报
回复
用游标 循环出来一个临时表 返回这个临时表
allanic 2009-02-07
  • 打赏
  • 举报
回复
假设id是连续的(中间没有跳号)
select a.* from t a where exists(select 1 from t b where b.id between a.id and a.id+5 and b.times<>0)
上面的sql嵌套了一层,不知性能上能否接受。
如果id不连续或者需要更高的性能,可以用存储过程,通过两个cursor解决,也不是很复杂。
kao331431214 2009-02-07
  • 打赏
  • 举报
回复
不会 建议你去 SQL版问下

67,515

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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