id date times
10 2009-01-01 3
11 2009-01-02 1
12 2009-01-03 3
13 2009-01-04 3
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 1
24 2009-01-09 3
25 2009-01-10 3
26 2009-01-09 0
27 2009-01-09 0
如何根据一个区间统计出跟它一样的区间?
比如以上的A表中,2009-01-02,2009-01-03,2009-01-04三天时间内,times分别为1,3,3,该如何写一条SQL语句或
存储过程找出2009-01-08 - 2009-01-10这个区间呢?因为他的times也分别为1,3,3.
当然了,数据量比较大的,希望高手帮写一个效率较高的存储过程或SQL语句.谢谢了.
83 个解决方案
#1
没明白你说啥
#2
你那些日期很多重复的,这个才麻烦。
#3
声明一下,日期不会重复的,上边给出的是没有处理过的,上边只是举个例子.
#4
declare @t table(id int,date datetime,times int)
insert @t select 10,'2009-01-01',3
insert @t select 11,'2009-01-02',1
insert @t select 12,'2009-01-03',3
insert @t select 13,'2009-01-04',3
insert @t select 14,'2009-01-05',2
insert @t select 15,'2009-01-06',0
insert @t select 16,'2009-01-07',0
insert @t select 17,'2009-01-08',1
insert @t select 18,'2009-01-09',0
insert @t select 19,'2009-01-10',0
insert @t select 20,'2009-01-11',2
insert @t select 21,'2009-01-12',0
insert @t select 22,'2009-01-13',0
insert @t select 23,'2009-01-14',1
insert @t select 24,'2009-01-15',3
insert @t select 25,'2009-01-16',3
insert @t select 26,'2009-01-18',0
insert @t select 27,'2009-01-19',0
declare @begdate datetime,@enddate datetime
select @begdate='2009-01-02',
@enddate='2009-01-04'
select *
from (
select *
from @t a
where not exists(select 1 from @t where id=a.id and id not in(select id from @t where date between @begdate and @enddate))
) t
where exists(select 1 from @t where id=t.id and date between @begdate and @enddate)
id date times
----------- ----------------------- -----------
11 2009-01-02 00:00:00.000 1
12 2009-01-03 00:00:00.000 3
13 2009-01-04 00:00:00.000 3
(3 行受影响)
#5
if object_id ('A') is not null
drop table A
if OBJECT_ID('pro_c') is not null
drop procedure pro_c
go
create table A (id int,[date] datetime ,times int)
insert into A select 10,'2009-01-01',3
union all select 11,'2009-01-02',1
union all select 12,'2009-01-03',3
union all select 13,'2009-01-04',3
union all select 14,'2009-01-05',2
union all select 15,'2009-01-06',0
union all select 16,'2009-01-07',0
union all select 17,'2009-01-08',0
union all select 18,'2009-01-09',0
union all select 19,'2009-01-10',0
union all select 20,'2009-01-05',6
union all select 21,'2009-01-06',0
union all select 22,'2009-01-07',0
union all select 23,'2009-01-08',1
union all select 24,'2009-01-09',3
union all select 25,'2009-01-10',3
union all select 26,'2009-01-09',0
union all select 27,'2009-01-09',0
go
create procedure pro_c (@da1 datetime,@da2 datetime)
as
set nocount on
select * from A where times in
(select times from A WHERE [DATE] in ('2009-01-02','2009-01-03','2009-01-04'))
and [date] between @da1 and @da2
set nocount off
go
exec pro_c '2009-01-08','2009-01-10'
(18 行受影响)
id date times
----------- ----------------------- -----------
23 2009-01-08 00:00:00.000 1
24 2009-01-09 00:00:00.000 3
25 2009-01-10 00:00:00.000 3
#6
if object_id ('A') is not null
drop table A
if OBJECT_ID('pro_c') is not null
drop procedure pro_c
go
create table A (id int,[date] datetime ,times int)
insert into A select 10,'2009-01-01',3
union all select 11,'2009-01-02',1
union all select 12,'2009-01-03',3
union all select 13,'2009-01-04',3
union all select 14,'2009-01-05',2
union all select 15,'2009-01-06',0
union all select 16,'2009-01-07',0
union all select 17,'2009-01-08',0
union all select 18,'2009-01-09',0
union all select 19,'2009-01-10',0
union all select 20,'2009-01-05',6
union all select 21,'2009-01-06',0
union all select 22,'2009-01-07',0
union all select 23,'2009-01-08',1
union all select 24,'2009-01-09',3
union all select 25,'2009-01-10',3
union all select 26,'2009-01-09',0
union all select 27,'2009-01-09',0
go
create procedure pro_c (@da1 datetime,@da2 datetime)
as
set nocount on
select * from A where times in
(select times from A WHERE [DATE] in ('2009-01-02','2009-01-03','2009-01-04'))
and [date] between @da1 and @da2
set nocount off
go
exec pro_c '2009-01-08','2009-01-10'
(18 行受影响)
id date times
----------- ----------------------- -----------
23 2009-01-08 00:00:00.000 1
24 2009-01-09 00:00:00.000 3
25 2009-01-10 00:00:00.000 3
#7
declare @t table(id int,date datetime,times int)
insert @t select 10,'2009-01-01',3
insert @t select 11,'2009-01-02',1
insert @t select 12,'2009-01-03',3
insert @t select 13,'2009-01-04',3
insert @t select 14,'2009-01-05',2
insert @t select 15,'2009-01-06',0
insert @t select 16,'2009-01-07',0
insert @t select 17,'2009-01-08',1
insert @t select 18,'2009-01-09',0
insert @t select 19,'2009-01-10',0
insert @t select 20,'2009-01-11',2
insert @t select 21,'2009-01-12',0
insert @t select 22,'2009-01-13',0
insert @t select 23,'2009-01-14',1
insert @t select 24,'2009-01-15',3
insert @t select 25,'2009-01-16',3
insert @t select 26,'2009-01-18',0
insert @t select 27,'2009-01-19',0
declare @begdate datetime,@enddate datetime
select @begdate='2009-01-05',
@enddate='2009-01-08'
select *
from (
select *
from @t a
where not exists(select 1 from @t where id=a.id and id not in(select id from @t where date between @begdate and @enddate))
) t
where exists(select 1 from @t where id=t.id and date between @begdate and @enddate)
id date times
----------- ----------------------- -----------
14 2009-01-05 00:00:00.000 2
15 2009-01-06 00:00:00.000 0
16 2009-01-07 00:00:00.000 0
17 2009-01-08 00:00:00.000 1
(4 行受影响)
#8
ChinaJiaBing ,你的方法会列出所有单个符合条件的记录,比如下边的2009-01-01,能否加入一些条件,只选出完全匹配一个区间的?
select * from A where times in
(select times from A WHERE [DATE] in ('2009-01-02','2009-01-03','2009-01-04'))
and [date] between '2009-01-01' and '2009-01-21'
----------- ------------------------------------------------------ ----------- -----------
10 2009-01-01 00:00:00.000 3 2
11 2009-01-02 00:00:00.000 1 3
12 2009-01-03 00:00:00.000 3 2
13 2009-01-04 00:00:00.000 3 1
23 2009-01-08 00:00:00.000 1 3
24 2009-01-09 00:00:00.000 3 2
25 2009-01-10 00:00:00.000 3 1
(所影响的行数为 7 行)
#9
不好意思,上面有BUG,参考以下:
declare @t table(id int,date datetime,times int)
insert @t select 10,'2009-01-01',3
insert @t select 11,'2009-01-02',1
insert @t select 12,'2009-01-03',3
insert @t select 13,'2009-01-04',3
insert @t select 14,'2009-01-05',2
insert @t select 15,'2009-01-06',0
insert @t select 16,'2009-01-07',0
insert @t select 17,'2009-01-08',1
insert @t select 18,'2009-01-09',0
insert @t select 19,'2009-01-10',0
insert @t select 20,'2009-01-11',2
insert @t select 21,'2009-01-12',0
insert @t select 22,'2009-01-13',0
insert @t select 23,'2009-01-14',1
insert @t select 24,'2009-01-15',3
insert @t select 25,'2009-01-16',3
insert @t select 26,'2009-01-18',0
insert @t select 27,'2009-01-19',0
declare @begdate datetime,@enddate datetime
select @begdate='2009-01-05',
@enddate='2009-01-08'
select *
from (
select *
from @t a
where not exists(select 1 from @t where id=a.id and id in(select id from @t where date between @begdate and @enddate))
) t
where exists(
select *
from @t b
where exists(select 1 from @t where id=b.id and times in(select times from @t where date between @begdate and @enddate))
and b.id=t.id)
id date times
----------- ----------------------- -----------
11 2009-01-02 00:00:00.000 1
18 2009-01-09 00:00:00.000 0
19 2009-01-10 00:00:00.000 0
20 2009-01-11 00:00:00.000 2
21 2009-01-12 00:00:00.000 0
22 2009-01-13 00:00:00.000 0
23 2009-01-14 00:00:00.000 1
26 2009-01-18 00:00:00.000 0
27 2009-01-19 00:00:00.000 0
(9 行受影响)
#10
学习..
#11
这个好难呀 记号一下。
要查找的区间是固定的吗
要查找的区间是固定的吗
#12
--用的九楼的数据,把需要的条件放入一个临时表.速度不知道怎么样?试试吧.
create table tb (id int,date datetime,times int)
insert tb select 10,'2009-01-01',3
insert tb select 11,'2009-01-02',1
insert tb select 12,'2009-01-03',3
insert tb select 13,'2009-01-04',3
insert tb select 14,'2009-01-05',2
insert tb select 15,'2009-01-06',0
insert tb select 16,'2009-01-07',0
insert tb select 17,'2009-01-08',1
insert tb select 18,'2009-01-09',0
insert tb select 19,'2009-01-10',0
insert tb select 20,'2009-01-11',2
insert tb select 21,'2009-01-12',0
insert tb select 22,'2009-01-13',0
insert tb select 23,'2009-01-14',1
insert tb select 24,'2009-01-15',3
insert tb select 25,'2009-01-16',3
insert tb select 26,'2009-01-18',0
insert tb select 27,'2009-01-19',0
go
--建立一个临时表
create table tb2 (id int,date datetime,times int)
insert tb2 select 1,'2009-01-02',1
insert tb2 select 2,'2009-01-03',3
insert tb2 select 3,'2009-01-04',3
go
select m.* from tb m,
(
select t1.id id1, t2.id id2, t3.id id3 from
(select t.* from tb t, tb2 n where t.times = n.times and n.id = 1) t1,
(select t.* from tb t, tb2 n where t.times = n.times and n.id = 2) t2,
(select t.* from tb t, tb2 n where t.times = n.times and n.id = 3) t3
where datediff(day,t1.date,t2.date) = 1 and datediff(day,t2.date,t3.date) = 1
) n
where m.id = n.id1 or m.id = n.id2 or m.id = n.id3
order by id
drop table tb,tb2
/*
id date times
----------- ------------------------------------------------------ -----------
11 2009-01-02 00:00:00.000 1
12 2009-01-03 00:00:00.000 3
13 2009-01-04 00:00:00.000 3
23 2009-01-14 00:00:00.000 1
24 2009-01-15 00:00:00.000 3
25 2009-01-16 00:00:00.000 3
(所影响的行数为 6 行)
*/
#13
老D,这个在扩展查询方面有点不方便,如:
需要改了代码后才能查出来
create table tb (id int,date datetime,times int)
insert tb select 10,'2009-01-01',3
insert tb select 11,'2009-01-02',1
insert tb select 12,'2009-01-03',3
insert tb select 13,'2009-01-04',3
insert tb select 14,'2009-01-05',2
insert tb select 15,'2009-01-06',0
insert tb select 16,'2009-01-07',0
insert tb select 17,'2009-01-08',1
insert tb select 18,'2009-01-09',0
insert tb select 19,'2009-01-10',0
insert tb select 20,'2009-01-11',2
insert tb select 21,'2009-01-12',0
insert tb select 22,'2009-01-13',0
insert tb select 23,'2009-01-14',1
insert tb select 24,'2009-01-15',3
insert tb select 25,'2009-01-16',3
insert tb select 26,'2009-01-18',0
insert tb select 27,'2009-01-19',0
go
declare @begdate datetime,@enddate datetime
select @begdate='2009-01-05',
@enddate='2009-01-08'
--建立一个临时表
select id=identity(int,1,1),date,times into tb2
from tb where date between @begdate and @enddate
go
--开始查询
select m.* from tb m,
(
select t1.id id1, t2.id id2, t3.id id3 ,t4.id id4 from
(select t.* from tb t, tb2 n where t.times = n.times and n.id = 1) t1,
(select t.* from tb t, tb2 n where t.times = n.times and n.id = 2) t2,
(select t.* from tb t, tb2 n where t.times = n.times and n.id = 3) t3,
(select t.* from tb t, tb2 n where t.times = n.times and n.id = 4) t4
where datediff(day,t1.date,t2.date) = 1 and datediff(day,t2.date,t3.date) = 1 and datediff(day,t3.date,t4.date) = 1
) n
where m.id = n.id1 or m.id = n.id2 or m.id = n.id3 or m.id=n.id4
order by id
drop table tb,tb2
id date times
----------- ----------------------- -----------
14 2009-01-05 00:00:00.000 2
15 2009-01-06 00:00:00.000 0
16 2009-01-07 00:00:00.000 0
17 2009-01-08 00:00:00.000 1
20 2009-01-11 00:00:00.000 2
21 2009-01-12 00:00:00.000 0
22 2009-01-13 00:00:00.000 0
23 2009-01-14 00:00:00.000 1
(8 行受影响)
需要改了代码后才能查出来
#14
如果条件不定,不好搞.
#15
睡觉了,时候不早了
#16
好像现在还没有人完全实现这个功能哦,看来要用字符串匹配了。
SQL直接查恐怕不容易,但是字符串匹配效率又太低..
等待高手...
#17
九楼tony的方法在下面情况时失效:
@begdate='2009-01-04'
@enddate='2009-01-05'
#18
选出完全匹配一个区间的
-->>是什么意思呢?就8楼的结果,是从上面选出随便一个子集还是区间是固定的?
-->>是什么意思呢?就8楼的结果,是从上面选出随便一个子集还是区间是固定的?
#19
再说一下要求,可能有些朋友还没有理解:
假设有以下结构的表A(其中日期是连续的,且不会重复):
id date times
10 2009-01-01 3
11 2009-01-02 1
12 2009-01-03 3
13 2009-01-04 3
14 2009-01-05 2
15 2009-01-06 0
16 2009-01-07 0
17 2009-01-08 1
18 2009-01-09 3
19 2009-01-10 3
20 2009-01-11 0
21 2009-01-12 0
22 2009-01-13 1
23 2009-01-14 3
24 2009-01-15 3
现在假设我已经知道了2009-01-02~2009-01-04这连续的3天中,times的值分别为1,3,3. 现在要在整个表中找出所有连续区间(日期)中times的值完全与之匹配的区间,比如上边的2009-01-08~2009-01-10, 2009-01-13~2009-01-15两个区间,就是符合条件的,因为在这个区间中times的值也是1,3,3.
非常感谢各位朋友的踊跃参与,目前为止,还没有完全符合要求的解决方案.继续等待高手出现.
假设有以下结构的表A(其中日期是连续的,且不会重复):
id date times
10 2009-01-01 3
11 2009-01-02 1
12 2009-01-03 3
13 2009-01-04 3
14 2009-01-05 2
15 2009-01-06 0
16 2009-01-07 0
17 2009-01-08 1
18 2009-01-09 3
19 2009-01-10 3
20 2009-01-11 0
21 2009-01-12 0
22 2009-01-13 1
23 2009-01-14 3
24 2009-01-15 3
现在假设我已经知道了2009-01-02~2009-01-04这连续的3天中,times的值分别为1,3,3. 现在要在整个表中找出所有连续区间(日期)中times的值完全与之匹配的区间,比如上边的2009-01-08~2009-01-10, 2009-01-13~2009-01-15两个区间,就是符合条件的,因为在这个区间中times的值也是1,3,3.
非常感谢各位朋友的踊跃参与,目前为止,还没有完全符合要求的解决方案.继续等待高手出现.
#20
用游标或循环判断吧。
#21
偶顶
#22
用游标或循环判断吧。
#23
if object_id('[tb]') is not null drop table [tb]
go
create table [tb]([id] int,[date] datetime,[times] int)
insert [tb]
select 10,'2009-01-01',3 union all
select 11,'2009-01-02',1 union all
select 12,'2009-01-03',3 union all
select 13,'2009-01-04',3 union all
select 14,'2009-01-05',2 union all
select 15,'2009-01-06',0 union all
select 16,'2009-01-07',0 union all
select 17,'2009-01-08',1 union all
select 18,'2009-01-09',3 union all
select 19,'2009-01-10',3 union all
select 20,'2009-01-11',0 union all
select 21,'2009-01-12',0 union all
select 22,'2009-01-13',1 union all
select 23,'2009-01-14',3 union all
select 24,'2009-01-15',3 union all
select 25,'2009-01-16',1 union all
select 26,'2009-01-17',2 union all
select 27,'2009-01-18',3
go
--初始化
declare @b datetime,@e datetime,@d int,@bt int,@et int
select @b='2009-01-02',@e='2009-01-04',@d=datediff(d,@b,@e)
select @bt=times from tb where date=@b
select @et=times from tb where date=@e
--保存用于匹配的结果集
select rn=identity(int,0,1),* into # from tb where date between @b and @e
--求出匹配的所有集合中的第一条记录的id
select id into #1 from tb t
where times=@bt
and exists(select 1 from tb where times=@et and id=t.id+@d)
and not exists(select 1 from tb where date>t.date and date<t.date+@d and times<>(select times from # where rn=datediff(d,t.date,tb.date)))
--选出所有匹配的结果集
select * from tb a
join #1 b
on a.id between b.id and b.id+@d
/*
id date times id
----------- ----------------------- ----------- -----------
11 2009-01-02 00:00:00.000 1 11
12 2009-01-03 00:00:00.000 3 11
13 2009-01-04 00:00:00.000 3 11
17 2009-01-08 00:00:00.000 1 17
18 2009-01-09 00:00:00.000 3 17
19 2009-01-10 00:00:00.000 3 17
22 2009-01-13 00:00:00.000 1 22
23 2009-01-14 00:00:00.000 3 22
24 2009-01-15 00:00:00.000 3 22
(9 行受影响)
*/
drop table #
drop table #1
#24
select a.* from tb a
join #1 b
on a.id between b.id and b.id+@d
/*
id date times
----------- ----------------------- -----------
11 2009-01-02 00:00:00.000 1
12 2009-01-03 00:00:00.000 3
13 2009-01-04 00:00:00.000 3
17 2009-01-08 00:00:00.000 1
18 2009-01-09 00:00:00.000 3
19 2009-01-10 00:00:00.000 3
22 2009-01-13 00:00:00.000 1
23 2009-01-14 00:00:00.000 3
24 2009-01-15 00:00:00.000 3
(9 行受影响)
*/
#25
楼上是高手,和我的想法一样,嘿嘿
#26
WA
#27
做个记号,这个确实很难
#28
z着个看不懂啊
#29
高手真多啊顶
#30
高手出现了,呵呵.即23楼的szx1999(蓉儿),她给出的就是解决方案的思路及答案,经验证效率非常高.敬仰中...... :)
也非常感谢积极参与的各位.
也非常感谢积极参与的各位.
#31
good
#32
UP
#33
学习了
#34
貌似好多高手 学习中···
#35
好东东
#36
都是高手,学习中
#37
ding
#38
echo "你们太牛B了";
#39
[img=http://www.qilvr.com/line/details_6d525919-c722-43f3-802d-8f6c9d952f4e.htm][/img]
问题没看明白,不过回答的很好,看明白了
问题没看明白,不过回答的很好,看明白了
#40
学习学习
#41
有点困难!!
#42
学习,学习
#43
恩,不错学习了
#44
有点意思
#45
高手很多啊,估计纯sql有点麻烦啊
#46
好貼﹐學習
#47
mark……
#48
浏览者
马克。。。。
马克。。。。
#49
id date times
10 2009-01-01 3
11 2009-01-02 1
12 2009-01-03 3
13 2009-01-04 3
select id,data,issame,count() over (partition by issame) from (
select id,data,to_char(times)||to_char(nextday)||to_char(next2day) issame from (
select id,data,times,nextday,lead(nextday) over (order by times) next2day from (
select id,data,times,lead(times) over(order by times)nextday from table
)))
select id,data,times,lead(times) over(order by times)nextday from table 这里取得下一天的次数,
select id,data,times,nextday,lead(nextday) over (order by times) next2day from ( 这里取得下峡谷天的次数,
select id,data,to_char(times)||to_char(nextday)||to_char(next2day) issame from (这里是把三个次数合并,
select id,data,issame,count() over (partition by issame) from (这里用分组的方式去判断这边的有多少个
10 2009-01-01 3
11 2009-01-02 1
12 2009-01-03 3
13 2009-01-04 3
select id,data,issame,count() over (partition by issame) from (
select id,data,to_char(times)||to_char(nextday)||to_char(next2day) issame from (
select id,data,times,nextday,lead(nextday) over (order by times) next2day from (
select id,data,times,lead(times) over(order by times)nextday from table
)))
select id,data,times,lead(times) over(order by times)nextday from table 这里取得下一天的次数,
select id,data,times,nextday,lead(nextday) over (order by times) next2day from ( 这里取得下峡谷天的次数,
select id,data,to_char(times)||to_char(nextday)||to_char(next2day) issame from (这里是把三个次数合并,
select id,data,issame,count() over (partition by issame) from (这里用分组的方式去判断这边的有多少个
#50
不明白!!!!!!!!!!
#1
没明白你说啥
#2
你那些日期很多重复的,这个才麻烦。
#3
声明一下,日期不会重复的,上边给出的是没有处理过的,上边只是举个例子.
#4
declare @t table(id int,date datetime,times int)
insert @t select 10,'2009-01-01',3
insert @t select 11,'2009-01-02',1
insert @t select 12,'2009-01-03',3
insert @t select 13,'2009-01-04',3
insert @t select 14,'2009-01-05',2
insert @t select 15,'2009-01-06',0
insert @t select 16,'2009-01-07',0
insert @t select 17,'2009-01-08',1
insert @t select 18,'2009-01-09',0
insert @t select 19,'2009-01-10',0
insert @t select 20,'2009-01-11',2
insert @t select 21,'2009-01-12',0
insert @t select 22,'2009-01-13',0
insert @t select 23,'2009-01-14',1
insert @t select 24,'2009-01-15',3
insert @t select 25,'2009-01-16',3
insert @t select 26,'2009-01-18',0
insert @t select 27,'2009-01-19',0
declare @begdate datetime,@enddate datetime
select @begdate='2009-01-02',
@enddate='2009-01-04'
select *
from (
select *
from @t a
where not exists(select 1 from @t where id=a.id and id not in(select id from @t where date between @begdate and @enddate))
) t
where exists(select 1 from @t where id=t.id and date between @begdate and @enddate)
id date times
----------- ----------------------- -----------
11 2009-01-02 00:00:00.000 1
12 2009-01-03 00:00:00.000 3
13 2009-01-04 00:00:00.000 3
(3 行受影响)
#5
if object_id ('A') is not null
drop table A
if OBJECT_ID('pro_c') is not null
drop procedure pro_c
go
create table A (id int,[date] datetime ,times int)
insert into A select 10,'2009-01-01',3
union all select 11,'2009-01-02',1
union all select 12,'2009-01-03',3
union all select 13,'2009-01-04',3
union all select 14,'2009-01-05',2
union all select 15,'2009-01-06',0
union all select 16,'2009-01-07',0
union all select 17,'2009-01-08',0
union all select 18,'2009-01-09',0
union all select 19,'2009-01-10',0
union all select 20,'2009-01-05',6
union all select 21,'2009-01-06',0
union all select 22,'2009-01-07',0
union all select 23,'2009-01-08',1
union all select 24,'2009-01-09',3
union all select 25,'2009-01-10',3
union all select 26,'2009-01-09',0
union all select 27,'2009-01-09',0
go
create procedure pro_c (@da1 datetime,@da2 datetime)
as
set nocount on
select * from A where times in
(select times from A WHERE [DATE] in ('2009-01-02','2009-01-03','2009-01-04'))
and [date] between @da1 and @da2
set nocount off
go
exec pro_c '2009-01-08','2009-01-10'
(18 行受影响)
id date times
----------- ----------------------- -----------
23 2009-01-08 00:00:00.000 1
24 2009-01-09 00:00:00.000 3
25 2009-01-10 00:00:00.000 3
#6
if object_id ('A') is not null
drop table A
if OBJECT_ID('pro_c') is not null
drop procedure pro_c
go
create table A (id int,[date] datetime ,times int)
insert into A select 10,'2009-01-01',3
union all select 11,'2009-01-02',1
union all select 12,'2009-01-03',3
union all select 13,'2009-01-04',3
union all select 14,'2009-01-05',2
union all select 15,'2009-01-06',0
union all select 16,'2009-01-07',0
union all select 17,'2009-01-08',0
union all select 18,'2009-01-09',0
union all select 19,'2009-01-10',0
union all select 20,'2009-01-05',6
union all select 21,'2009-01-06',0
union all select 22,'2009-01-07',0
union all select 23,'2009-01-08',1
union all select 24,'2009-01-09',3
union all select 25,'2009-01-10',3
union all select 26,'2009-01-09',0
union all select 27,'2009-01-09',0
go
create procedure pro_c (@da1 datetime,@da2 datetime)
as
set nocount on
select * from A where times in
(select times from A WHERE [DATE] in ('2009-01-02','2009-01-03','2009-01-04'))
and [date] between @da1 and @da2
set nocount off
go
exec pro_c '2009-01-08','2009-01-10'
(18 行受影响)
id date times
----------- ----------------------- -----------
23 2009-01-08 00:00:00.000 1
24 2009-01-09 00:00:00.000 3
25 2009-01-10 00:00:00.000 3
#7
declare @t table(id int,date datetime,times int)
insert @t select 10,'2009-01-01',3
insert @t select 11,'2009-01-02',1
insert @t select 12,'2009-01-03',3
insert @t select 13,'2009-01-04',3
insert @t select 14,'2009-01-05',2
insert @t select 15,'2009-01-06',0
insert @t select 16,'2009-01-07',0
insert @t select 17,'2009-01-08',1
insert @t select 18,'2009-01-09',0
insert @t select 19,'2009-01-10',0
insert @t select 20,'2009-01-11',2
insert @t select 21,'2009-01-12',0
insert @t select 22,'2009-01-13',0
insert @t select 23,'2009-01-14',1
insert @t select 24,'2009-01-15',3
insert @t select 25,'2009-01-16',3
insert @t select 26,'2009-01-18',0
insert @t select 27,'2009-01-19',0
declare @begdate datetime,@enddate datetime
select @begdate='2009-01-05',
@enddate='2009-01-08'
select *
from (
select *
from @t a
where not exists(select 1 from @t where id=a.id and id not in(select id from @t where date between @begdate and @enddate))
) t
where exists(select 1 from @t where id=t.id and date between @begdate and @enddate)
id date times
----------- ----------------------- -----------
14 2009-01-05 00:00:00.000 2
15 2009-01-06 00:00:00.000 0
16 2009-01-07 00:00:00.000 0
17 2009-01-08 00:00:00.000 1
(4 行受影响)
#8
ChinaJiaBing ,你的方法会列出所有单个符合条件的记录,比如下边的2009-01-01,能否加入一些条件,只选出完全匹配一个区间的?
select * from A where times in
(select times from A WHERE [DATE] in ('2009-01-02','2009-01-03','2009-01-04'))
and [date] between '2009-01-01' and '2009-01-21'
----------- ------------------------------------------------------ ----------- -----------
10 2009-01-01 00:00:00.000 3 2
11 2009-01-02 00:00:00.000 1 3
12 2009-01-03 00:00:00.000 3 2
13 2009-01-04 00:00:00.000 3 1
23 2009-01-08 00:00:00.000 1 3
24 2009-01-09 00:00:00.000 3 2
25 2009-01-10 00:00:00.000 3 1
(所影响的行数为 7 行)
#9
不好意思,上面有BUG,参考以下:
declare @t table(id int,date datetime,times int)
insert @t select 10,'2009-01-01',3
insert @t select 11,'2009-01-02',1
insert @t select 12,'2009-01-03',3
insert @t select 13,'2009-01-04',3
insert @t select 14,'2009-01-05',2
insert @t select 15,'2009-01-06',0
insert @t select 16,'2009-01-07',0
insert @t select 17,'2009-01-08',1
insert @t select 18,'2009-01-09',0
insert @t select 19,'2009-01-10',0
insert @t select 20,'2009-01-11',2
insert @t select 21,'2009-01-12',0
insert @t select 22,'2009-01-13',0
insert @t select 23,'2009-01-14',1
insert @t select 24,'2009-01-15',3
insert @t select 25,'2009-01-16',3
insert @t select 26,'2009-01-18',0
insert @t select 27,'2009-01-19',0
declare @begdate datetime,@enddate datetime
select @begdate='2009-01-05',
@enddate='2009-01-08'
select *
from (
select *
from @t a
where not exists(select 1 from @t where id=a.id and id in(select id from @t where date between @begdate and @enddate))
) t
where exists(
select *
from @t b
where exists(select 1 from @t where id=b.id and times in(select times from @t where date between @begdate and @enddate))
and b.id=t.id)
id date times
----------- ----------------------- -----------
11 2009-01-02 00:00:00.000 1
18 2009-01-09 00:00:00.000 0
19 2009-01-10 00:00:00.000 0
20 2009-01-11 00:00:00.000 2
21 2009-01-12 00:00:00.000 0
22 2009-01-13 00:00:00.000 0
23 2009-01-14 00:00:00.000 1
26 2009-01-18 00:00:00.000 0
27 2009-01-19 00:00:00.000 0
(9 行受影响)
#10
学习..
#11
这个好难呀 记号一下。
要查找的区间是固定的吗
要查找的区间是固定的吗
#12
--用的九楼的数据,把需要的条件放入一个临时表.速度不知道怎么样?试试吧.
create table tb (id int,date datetime,times int)
insert tb select 10,'2009-01-01',3
insert tb select 11,'2009-01-02',1
insert tb select 12,'2009-01-03',3
insert tb select 13,'2009-01-04',3
insert tb select 14,'2009-01-05',2
insert tb select 15,'2009-01-06',0
insert tb select 16,'2009-01-07',0
insert tb select 17,'2009-01-08',1
insert tb select 18,'2009-01-09',0
insert tb select 19,'2009-01-10',0
insert tb select 20,'2009-01-11',2
insert tb select 21,'2009-01-12',0
insert tb select 22,'2009-01-13',0
insert tb select 23,'2009-01-14',1
insert tb select 24,'2009-01-15',3
insert tb select 25,'2009-01-16',3
insert tb select 26,'2009-01-18',0
insert tb select 27,'2009-01-19',0
go
--建立一个临时表
create table tb2 (id int,date datetime,times int)
insert tb2 select 1,'2009-01-02',1
insert tb2 select 2,'2009-01-03',3
insert tb2 select 3,'2009-01-04',3
go
select m.* from tb m,
(
select t1.id id1, t2.id id2, t3.id id3 from
(select t.* from tb t, tb2 n where t.times = n.times and n.id = 1) t1,
(select t.* from tb t, tb2 n where t.times = n.times and n.id = 2) t2,
(select t.* from tb t, tb2 n where t.times = n.times and n.id = 3) t3
where datediff(day,t1.date,t2.date) = 1 and datediff(day,t2.date,t3.date) = 1
) n
where m.id = n.id1 or m.id = n.id2 or m.id = n.id3
order by id
drop table tb,tb2
/*
id date times
----------- ------------------------------------------------------ -----------
11 2009-01-02 00:00:00.000 1
12 2009-01-03 00:00:00.000 3
13 2009-01-04 00:00:00.000 3
23 2009-01-14 00:00:00.000 1
24 2009-01-15 00:00:00.000 3
25 2009-01-16 00:00:00.000 3
(所影响的行数为 6 行)
*/
#13
老D,这个在扩展查询方面有点不方便,如:
需要改了代码后才能查出来
create table tb (id int,date datetime,times int)
insert tb select 10,'2009-01-01',3
insert tb select 11,'2009-01-02',1
insert tb select 12,'2009-01-03',3
insert tb select 13,'2009-01-04',3
insert tb select 14,'2009-01-05',2
insert tb select 15,'2009-01-06',0
insert tb select 16,'2009-01-07',0
insert tb select 17,'2009-01-08',1
insert tb select 18,'2009-01-09',0
insert tb select 19,'2009-01-10',0
insert tb select 20,'2009-01-11',2
insert tb select 21,'2009-01-12',0
insert tb select 22,'2009-01-13',0
insert tb select 23,'2009-01-14',1
insert tb select 24,'2009-01-15',3
insert tb select 25,'2009-01-16',3
insert tb select 26,'2009-01-18',0
insert tb select 27,'2009-01-19',0
go
declare @begdate datetime,@enddate datetime
select @begdate='2009-01-05',
@enddate='2009-01-08'
--建立一个临时表
select id=identity(int,1,1),date,times into tb2
from tb where date between @begdate and @enddate
go
--开始查询
select m.* from tb m,
(
select t1.id id1, t2.id id2, t3.id id3 ,t4.id id4 from
(select t.* from tb t, tb2 n where t.times = n.times and n.id = 1) t1,
(select t.* from tb t, tb2 n where t.times = n.times and n.id = 2) t2,
(select t.* from tb t, tb2 n where t.times = n.times and n.id = 3) t3,
(select t.* from tb t, tb2 n where t.times = n.times and n.id = 4) t4
where datediff(day,t1.date,t2.date) = 1 and datediff(day,t2.date,t3.date) = 1 and datediff(day,t3.date,t4.date) = 1
) n
where m.id = n.id1 or m.id = n.id2 or m.id = n.id3 or m.id=n.id4
order by id
drop table tb,tb2
id date times
----------- ----------------------- -----------
14 2009-01-05 00:00:00.000 2
15 2009-01-06 00:00:00.000 0
16 2009-01-07 00:00:00.000 0
17 2009-01-08 00:00:00.000 1
20 2009-01-11 00:00:00.000 2
21 2009-01-12 00:00:00.000 0
22 2009-01-13 00:00:00.000 0
23 2009-01-14 00:00:00.000 1
(8 行受影响)
需要改了代码后才能查出来
#14
如果条件不定,不好搞.
#15
睡觉了,时候不早了
#16
好像现在还没有人完全实现这个功能哦,看来要用字符串匹配了。
SQL直接查恐怕不容易,但是字符串匹配效率又太低..
等待高手...
#17
九楼tony的方法在下面情况时失效:
@begdate='2009-01-04'
@enddate='2009-01-05'
#18
选出完全匹配一个区间的
-->>是什么意思呢?就8楼的结果,是从上面选出随便一个子集还是区间是固定的?
-->>是什么意思呢?就8楼的结果,是从上面选出随便一个子集还是区间是固定的?
#19
再说一下要求,可能有些朋友还没有理解:
假设有以下结构的表A(其中日期是连续的,且不会重复):
id date times
10 2009-01-01 3
11 2009-01-02 1
12 2009-01-03 3
13 2009-01-04 3
14 2009-01-05 2
15 2009-01-06 0
16 2009-01-07 0
17 2009-01-08 1
18 2009-01-09 3
19 2009-01-10 3
20 2009-01-11 0
21 2009-01-12 0
22 2009-01-13 1
23 2009-01-14 3
24 2009-01-15 3
现在假设我已经知道了2009-01-02~2009-01-04这连续的3天中,times的值分别为1,3,3. 现在要在整个表中找出所有连续区间(日期)中times的值完全与之匹配的区间,比如上边的2009-01-08~2009-01-10, 2009-01-13~2009-01-15两个区间,就是符合条件的,因为在这个区间中times的值也是1,3,3.
非常感谢各位朋友的踊跃参与,目前为止,还没有完全符合要求的解决方案.继续等待高手出现.
假设有以下结构的表A(其中日期是连续的,且不会重复):
id date times
10 2009-01-01 3
11 2009-01-02 1
12 2009-01-03 3
13 2009-01-04 3
14 2009-01-05 2
15 2009-01-06 0
16 2009-01-07 0
17 2009-01-08 1
18 2009-01-09 3
19 2009-01-10 3
20 2009-01-11 0
21 2009-01-12 0
22 2009-01-13 1
23 2009-01-14 3
24 2009-01-15 3
现在假设我已经知道了2009-01-02~2009-01-04这连续的3天中,times的值分别为1,3,3. 现在要在整个表中找出所有连续区间(日期)中times的值完全与之匹配的区间,比如上边的2009-01-08~2009-01-10, 2009-01-13~2009-01-15两个区间,就是符合条件的,因为在这个区间中times的值也是1,3,3.
非常感谢各位朋友的踊跃参与,目前为止,还没有完全符合要求的解决方案.继续等待高手出现.
#20
用游标或循环判断吧。
#21
偶顶
#22
用游标或循环判断吧。
#23
if object_id('[tb]') is not null drop table [tb]
go
create table [tb]([id] int,[date] datetime,[times] int)
insert [tb]
select 10,'2009-01-01',3 union all
select 11,'2009-01-02',1 union all
select 12,'2009-01-03',3 union all
select 13,'2009-01-04',3 union all
select 14,'2009-01-05',2 union all
select 15,'2009-01-06',0 union all
select 16,'2009-01-07',0 union all
select 17,'2009-01-08',1 union all
select 18,'2009-01-09',3 union all
select 19,'2009-01-10',3 union all
select 20,'2009-01-11',0 union all
select 21,'2009-01-12',0 union all
select 22,'2009-01-13',1 union all
select 23,'2009-01-14',3 union all
select 24,'2009-01-15',3 union all
select 25,'2009-01-16',1 union all
select 26,'2009-01-17',2 union all
select 27,'2009-01-18',3
go
--初始化
declare @b datetime,@e datetime,@d int,@bt int,@et int
select @b='2009-01-02',@e='2009-01-04',@d=datediff(d,@b,@e)
select @bt=times from tb where date=@b
select @et=times from tb where date=@e
--保存用于匹配的结果集
select rn=identity(int,0,1),* into # from tb where date between @b and @e
--求出匹配的所有集合中的第一条记录的id
select id into #1 from tb t
where times=@bt
and exists(select 1 from tb where times=@et and id=t.id+@d)
and not exists(select 1 from tb where date>t.date and date<t.date+@d and times<>(select times from # where rn=datediff(d,t.date,tb.date)))
--选出所有匹配的结果集
select * from tb a
join #1 b
on a.id between b.id and b.id+@d
/*
id date times id
----------- ----------------------- ----------- -----------
11 2009-01-02 00:00:00.000 1 11
12 2009-01-03 00:00:00.000 3 11
13 2009-01-04 00:00:00.000 3 11
17 2009-01-08 00:00:00.000 1 17
18 2009-01-09 00:00:00.000 3 17
19 2009-01-10 00:00:00.000 3 17
22 2009-01-13 00:00:00.000 1 22
23 2009-01-14 00:00:00.000 3 22
24 2009-01-15 00:00:00.000 3 22
(9 行受影响)
*/
drop table #
drop table #1
#24
select a.* from tb a
join #1 b
on a.id between b.id and b.id+@d
/*
id date times
----------- ----------------------- -----------
11 2009-01-02 00:00:00.000 1
12 2009-01-03 00:00:00.000 3
13 2009-01-04 00:00:00.000 3
17 2009-01-08 00:00:00.000 1
18 2009-01-09 00:00:00.000 3
19 2009-01-10 00:00:00.000 3
22 2009-01-13 00:00:00.000 1
23 2009-01-14 00:00:00.000 3
24 2009-01-15 00:00:00.000 3
(9 行受影响)
*/
#25
楼上是高手,和我的想法一样,嘿嘿
#26
WA
#27
做个记号,这个确实很难
#28
z着个看不懂啊
#29
高手真多啊顶
#30
高手出现了,呵呵.即23楼的szx1999(蓉儿),她给出的就是解决方案的思路及答案,经验证效率非常高.敬仰中...... :)
也非常感谢积极参与的各位.
也非常感谢积极参与的各位.
#31
good
#32
UP
#33
学习了
#34
貌似好多高手 学习中···
#35
好东东
#36
都是高手,学习中
#37
ding
#38
echo "你们太牛B了";
#39
[img=http://www.qilvr.com/line/details_6d525919-c722-43f3-802d-8f6c9d952f4e.htm][/img]
问题没看明白,不过回答的很好,看明白了
问题没看明白,不过回答的很好,看明白了
#40
学习学习
#41
有点困难!!
#42
学习,学习
#43
恩,不错学习了
#44
有点意思
#45
高手很多啊,估计纯sql有点麻烦啊
#46
好貼﹐學習
#47
mark……
#48
浏览者
马克。。。。
马克。。。。
#49
id date times
10 2009-01-01 3
11 2009-01-02 1
12 2009-01-03 3
13 2009-01-04 3
select id,data,issame,count() over (partition by issame) from (
select id,data,to_char(times)||to_char(nextday)||to_char(next2day) issame from (
select id,data,times,nextday,lead(nextday) over (order by times) next2day from (
select id,data,times,lead(times) over(order by times)nextday from table
)))
select id,data,times,lead(times) over(order by times)nextday from table 这里取得下一天的次数,
select id,data,times,nextday,lead(nextday) over (order by times) next2day from ( 这里取得下峡谷天的次数,
select id,data,to_char(times)||to_char(nextday)||to_char(next2day) issame from (这里是把三个次数合并,
select id,data,issame,count() over (partition by issame) from (这里用分组的方式去判断这边的有多少个
10 2009-01-01 3
11 2009-01-02 1
12 2009-01-03 3
13 2009-01-04 3
select id,data,issame,count() over (partition by issame) from (
select id,data,to_char(times)||to_char(nextday)||to_char(next2day) issame from (
select id,data,times,nextday,lead(nextday) over (order by times) next2day from (
select id,data,times,lead(times) over(order by times)nextday from table
)))
select id,data,times,lead(times) over(order by times)nextday from table 这里取得下一天的次数,
select id,data,times,nextday,lead(nextday) over (order by times) next2day from ( 这里取得下峡谷天的次数,
select id,data,to_char(times)||to_char(nextday)||to_char(next2day) issame from (这里是把三个次数合并,
select id,data,issame,count() over (partition by issame) from (这里用分组的方式去判断这边的有多少个
#50
不明白!!!!!!!!!!