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

找到唯一的区间

2012-12-14 
找出唯一的区间表格如下:id num timea09:01a19:02a19:03a19:04a09:05a19:06a19:07a19:08b19:01b19:02b19:0

找出唯一的区间
表格如下:

id num time
a   0    9:01
a   1    9:02
a   1    9:03
a   1    9:04
a   0    9:05
a   1    9:06
a   1    9:07
a   1    9:08


b   1    9:01
b   1    9:02
b   1    9:03
b   1    9:04
b   1    9:05
b   0    9:06
b   1    9:07
b   1    9:08


c   1    9:01
c   1    9:02
c   0    9:03
c   1    9:04
c   1    9:05
c   0    9:06
c   1    9:07
c   1    9:08


d   1    9:01
d   1    9:02
d   1    9:03
d   1    9:04
d   1    9:05
d   0    9:06
d   0    9:07
d   1    9:08


e   1    9:01
e   0    9:02
e   0    9:03
e   1    9:04
e   1    9:05
e   1    9:06
e   1    9:07
e   0    9:08


..  ..    ...

希望找出 某段时间内 连续是1 的最长区间,而且一定保证是唯一的一个。 

比如  e 9:04 9:07 全是1,而且 没有其他id 在9:04 9:07 重合。

    b 9:01 9:05  与 d 9:01 9:05 也都是1 ,但是重合,所以排除.

希望 找出 e 9:04 9:07这个区间。

2000系统, 
[最优解释]
DECLARE @timestamp NVARCHAR(4)

SET @timestamp='9:07'


--create #1
IF object_id('tempdb..#1')IS NOT NULL
    DROP TABLE #1
SELECT
        a.id,b.num,b.time,CONVERT(INT,0) AS count_id
    INTO #1
    FROM t1 AS a
INNER JOIN t1 AS b ON a.id=b.id AND b.time<=@timestamp AND b.time>ISNULL((SELECT MAX(time) FROM t1 AS x WHERE x.id=b.id AND x.time<=@timestamp AND x.num=0),'')
    WHERE a.time<=@timestamp
AND EXISTS(SELECT 1 FROM t1 AS x WHERE x.id=a.id AND x.time=@timestamp AND x.num=1)
GROUP BY a.id,b.num,b.time

UPDATE a
SET count_id=(SELECT COUNT(id) FROM #1 WHERE id=a.id)
FROM #1 AS a



SELECT 
a.id
,a.num
,a.time 
FROM #1 AS a


WHERE NOT EXISTS(SELECT 1 FROM #1 AS x
WHERE a.id<>x.id AND count_id>a.count_id
)
AND NOT EXISTS(SELECT 1 FROM #1 AS x
WHERE a.id<>x.id AND x.count_id=a.count_id
)


[其他解释]
---------------------------------
--  Author: HEROWANG(让你望见影子的墙)
--  Date  : 2012-11-05 16:08:55
--  blog  : blog.csdn.net/herowang
---------------------------------
 
IF OBJECT_ID('[tb]') IS NOT NULL 
    DROP TABLE [tb]
    drop table #t
    drop table #t2
go
CREATE TABLE [tb] (id VARCHAR(1),num INT,time datetime)
INSERT INTO [tb]
SELECT 'a',0,'9:01' UNION ALL
SELECT 'a',1,'9:02' UNION ALL
SELECT 'a',1,'9:03' UNION ALL
SELECT 'a',1,'9:04' UNION ALL
SELECT 'a',0,'9:05' UNION ALL
SELECT 'a',1,'9:06' UNION ALL
SELECT 'a',1,'9:07' UNION ALL
SELECT 'a',1,'9:08' UNION ALL
SELECT 'b',1,'9:01' UNION ALL
SELECT 'b',1,'9:02' UNION ALL
SELECT 'b',1,'9:03' UNION ALL
SELECT 'b',1,'9:04' UNION ALL
SELECT 'b',1,'9:05' UNION ALL
SELECT 'b',0,'9:06' UNION ALL
SELECT 'b',1,'9:07' UNION ALL
SELECT 'b',1,'9:08' UNION ALL
SELECT 'c',1,'9:01' UNION ALL
SELECT 'c',1,'9:02' UNION ALL
SELECT 'c',0,'9:03' UNION ALL
SELECT 'c',1,'9:04' UNION ALL
SELECT 'c',1,'9:05' UNION ALL
SELECT 'c',0,'9:06' UNION ALL
SELECT 'c',1,'9:07' UNION ALL
SELECT 'c',1,'9:08' UNION ALL
SELECT 'd',1,'9:01' UNION ALL
SELECT 'd',1,'9:02' UNION ALL
SELECT 'd',1,'9:03' UNION ALL
SELECT 'd',1,'9:04' UNION ALL
SELECT 'd',1,'9:05' UNION ALL
SELECT 'd',0,'9:06' UNION ALL
SELECT 'd',0,'9:07' UNION ALL
SELECT 'd',1,'9:08' UNION ALL
SELECT 'e',1,'9:01' UNION ALL
SELECT 'e',0,'9:02' UNION ALL
SELECT 'e',0,'9:03' UNION ALL
SELECT 'e',1,'9:04' UNION ALL
SELECT 'e',1,'9:05' UNION ALL
SELECT 'e',1,'9:06' UNION ALL
SELECT 'e',1,'9:07' UNION ALL
SELECT 'e',0,'9:08'
select px=identity(int,1,1),* into #t from tb
select distinct id,num,begintime=(select min(time) from #t where num=t.num and id=t.id and time<=t.time),
         endtime=(select max(time) from #t where num=t.num and id=t.id and time>t.time and px<(select top 1 px from #t where num!=t.num and id=t.id and px>t.px))
into #t2 
from [#t] t
where num=1

select top 1 *,diff=datediff(mi,begintime,endtime) from #t2
where endtime is not null  
order by datediff(mi,begintime,endtime) desc

e11900-01-01 09:01:00.0001900-01-01 09:07:00.0006


[其他解释]
哦,写的还是有些问题,54了吧
[其他解释]
高手都到哪里去了?


请出手吧!?
[其他解释]

----------------------------
-- Author  :TravyLee
-- Date    :2012-11-06 09:00:47
-- Version:
--      Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (Intel X86) 
--Jul  9 2008 14:43:34 
--Copyright (c) 1988-2008 Microsoft Corporation
--Developer Edition on Windows NT 6.1 <X86> (Build 7600: )
--
----------------------------
--> 测试数据:[test]
if object_id('[test]') is not null 
drop table [test]
go 
create table [test](
[id] varchar(1),
[num] int,
[time] time
)
insert [test]
select 'a',0,'9:01' union all
select 'a',1,'9:02' union all
select 'a',1,'9:03' union all
select 'a',1,'9:04' union all
select 'a',0,'9:05' union all
select 'a',1,'9:06' union all
select 'a',1,'9:07' union all
select 'a',1,'9:08' union all
select 'b',1,'9:01' union all
select 'b',1,'9:02' union all
select 'b',1,'9:03' union all
select 'b',1,'9:04' union all
select 'b',1,'9:05' union all
select 'b',0,'9:06' union all
select 'b',1,'9:07' union all
select 'b',1,'9:08' union all
select 'c',1,'9:01' union all
select 'c',1,'9:02' union all
select 'c',0,'9:03' union all
select 'c',1,'9:04' union all
select 'c',1,'9:05' union all
select 'c',0,'9:06' union all
select 'c',1,'9:07' union all
select 'c',1,'9:08' union all
select 'd',1,'9:01' union all
select 'd',1,'9:02' union all
select 'd',1,'9:03' union all
select 'd',1,'9:04' union all
select 'd',1,'9:05' union all
select 'd',0,'9:06' union all
select 'd',0,'9:07' union all
select 'd',1,'9:08' union all
select 'e',1,'9:01' union all
select 'e',0,'9:02' union all
select 'e',0,'9:03' union all
select 'e',1,'9:04' union all
select 'e',1,'9:05' union all
select 'e',1,'9:06' union all
select 'e',1,'9:07' union all
select 'e',0,'9:08'
--------------开始查询--------------------------

select 
*
from 
(select
*
from
(select
[id],
[num],
[time]
from
test
where
[time] between '9:01' and '9:05')t
where
not exists(select 1 from (select
[id],
[num],
[time]
from
test
where
[time] between '9:01' and '9:05')a where a.id=t.id and a.num<>t.num))a
where
not exists(select 1 from (select
*
from
(select
[id],
[num],
[time]


from
test
where
[time] between '9:01' and '9:05')t
where
not exists(select 1 from (select
[id],
[num],
[time]
from
test
where
[time] between '9:01' and '9:05')a where a.id=t.id and a.num<>t.num))m where a.time=m.time and a.id<>m.id)

/*
id   num         time
---- ----------- ----------------

(0 行受影响)


*/
select 
*
from 
(select
*
from
(select
[id],
[num],
[time]
from
test
where
[time] between '9:04' and '9:07')t
where
not exists(select 1 from (select
[id],
[num],
[time]
from
test
where
[time] between '9:04' and '9:07')a where a.id=t.id and a.num<>t.num))a
where
not exists(select 1 from (select
*
from
(select
[id],
[num],
[time]
from
test
where
[time] between '9:04' and '9:07')t
where
not exists(select 1 from (select
[id],
[num],
[time]
from
test
where
[time] between '9:04' and '9:07')a where a.id=t.id and a.num<>t.num))m where a.time=m.time and a.id<>m.id)
/*
id   num         time
---- ----------- ----------------
e    1           09:04:00.0000000
e    1           09:05:00.0000000
e    1           09:06:00.0000000
e    1           09:07:00.0000000

(4 行受影响)


*/


[其他解释]
4楼,

不知道 9:01-9:05 或者 9:04-9:07 这样的明确范围,

假设  可以确定一个时间点,比如 9:05 或者 9:07 这样子,另外一边不可知。
[其他解释]
顶起




高手请出手吧!? 
[其他解释]








这嵌套的!!









[其他解释]
引用:
4楼,

不知道 9:01-9:05 或者 9:04-9:07 这样的明确范围,

假设  可以确定一个时间点,比如 9:05 或者 9:07 这样子,另外一边不可知。


你条件都不知道  那怎么筛选数据
[其他解释]
假设 已经 可以确定一个时间点,比如 9:05 或者 9:07 这样子的终点 ,

回溯 找出 连续是1 的最长区间,而且一定保证是唯一的一个
[其他解释]
引用:
假设 已经 可以确定一个时间点,比如 9:05 或者 9:07 这样子的终点 ,

回溯 找出 连续是1 的最长区间,而且一定保证是唯一的一个


哥們,a 有兩個區間為3的阿.
------其他解决方案--------------------


是啊,有什么问题?

最长的区间是 e 9:04 9:07,没有重合的。

  b 9:01 9:05  与 d 9:01 9:05 长度为5 ,但是重合,所以排除.
[其他解释]

引用:
是啊,有什么问题?

最长的区间是 e 9:04 9:07,没有重合的。

  b 9:01 9:05  与 d 9:01 9:05 长度为5 ,但是重合,所以排除.


如果出現相同id,區間長度相同,隨便查詢1個,還是說全部都查詢?
[其他解释]
假设 已经 可以确定一个时间点,比如 9:05 或者 9:07 这样子的终点 ,

回溯 找出 连续是1 的最长区间,而且一定保证是唯一的一个 



[其他解释]
粗略寫了個.
USE test
go

--if object_id('t1') is not null 
--drop table t1
--Go
--Create table t1([id] nvarchar(1),[num] nvarchar(1),[time] datetime)
--Insert into t1
--Select N'a',N'0','9:01'
--Union all Select N'a',N'1','9:02'
--Union all Select N'a',N'1','9:03'
--Union all Select N'a',N'1','9:04'
--Union all Select N'a',N'0','9:05'
--Union all Select N'a',N'1','9:06'
--Union all Select N'a',N'1','9:07'
--Union all Select N'a',N'1','9:08'
--Union all Select N'b',N'1','9:01'
--Union all Select N'b',N'1','9:02'
--Union all Select N'b',N'1','9:03'
--Union all Select N'b',N'1','9:04'
--Union all Select N'b',N'1','9:05'
--Union all Select N'b',N'0','9:06'
--Union all Select N'b',N'1','9:07'
--Union all Select N'b',N'1','9:08'
--Union all Select N'c',N'1','9:01'
--Union all Select N'c',N'1','9:02'
--Union all Select N'c',N'0','9:03'
--Union all Select N'c',N'1','9:04'
--Union all Select N'c',N'1','9:05'
--Union all Select N'c',N'0','9:06'
--Union all Select N'c',N'1','9:07'
--Union all Select N'c',N'1','9:08'
--Union all Select N'd',N'1','9:01'
--Union all Select N'd',N'1','9:02'
--Union all Select N'd',N'1','9:03'
--Union all Select N'd',N'1','9:04'
--Union all Select N'd',N'1','9:05'
--Union all Select N'd',N'0','9:06'
--Union all Select N'd',N'0','9:07'
--Union all Select N'd',N'1','9:08'
--Union all Select N'e',N'1','9:01'
--Union all Select N'e',N'0','9:02'
--Union all Select N'e',N'0','9:03'
--Union all Select N'e',N'1','9:04'
--Union all Select N'e',N'1','9:05'
--Union all Select N'e',N'1','9:06'
--Union all Select N'e',N'1','9:07'
--Union all Select N'e',N'0','9:08'

--create #1
IF object_id('tempdb..#1')IS NOT NULL
DROP TABLE #1
SELECT
ROW_NUMBER()OVER(PARTITION BY id ORDER BY time) AS Row
,*
INTO #1
FROM t1

--create #2
IF object_id('tempdb..#2')IS NOT NULL
DROP TABLE #2
SELECT 
ROW_NUMBER()OVER(ORDER BY id ASC)AS Row
,id
,CONVERT(NVARCHAR(4000),'')AS Section_tmp


,CONVERT(BIT,0)AS Flag
INTO #2 
FROM #1 GROUP BY id

DECLARE @Sql NVARCHAR(MAX)

-- update #2
WHILE EXISTS(SELECT 1 FROM #2 WHERE Flag=0)
BEGIN

SET @Sql=''


SELECT @Sql=@Sql+CASE WHEN num=1 THEN LTRIM(Row) ELSE ',' END 
FROM #1
WHERE id=(SELECT TOP 1 id FROM #2 WHERE Flag=0 ORDER BY Row)

UPDATE #2
SET Section_tmp=@Sql
,Flag=1
WHERE id=(SELECT TOP 1 id FROM #2 WHERE Flag=0 ORDER BY Row)

END

--create #3
IF object_id('tempdb..#3')IS NOT NULL
DROP TABLE #3
CREATE TABLE #3(id NVARCHAR(1),Section bigint)

WHILE EXISTS(SELECT 1 FROM #2 WHERE Flag=1)
BEGIN

SET @Sql=''

SELECT @Sql=LTRIM(id)+''','''+REPLACE(Section_tmp,',',''' UNION SELECT '''+LTRIM(id)+''',''')+''''
FROM #2
WHERE id=(SELECT TOP 1 id from #2 WHERE Flag=1 ORDER BY Row)

UPDATE #2 SET Flag=0 WHERE id=(SELECT TOP 1 id FROM #2 WHERE Flag=1 ORDER BY Row)


INSERT INTO #3
EXEC ('SELECT N'''+@Sql)  

  
END


-- Result 1: 相同id,相同區間長度 查詢全部的區間.
SELECT a.id,a.num,a.time FROM #1 AS a,#3 AS b
WHERE a.id=b.id
AND CHARINDEX(LTRIM(a.Row),b.Section)>0
AND NOT EXISTS(SELECT 1 FROM #3 AS x
WHERE x.id=b.id AND LEN(x.Section)>LEN(b.Section)
)
GROUP BY a.id,a.num,a.time
ORDER BY a.id,a.time ASC


Go




[其他解释]
引用:
假设 已经 可以确定一个时间点,比如 9:05 或者 9:07 这样子的终点 ,

回溯 找出 连续是1 的最长区间,而且一定保证是唯一的一个


我都說了,你給的數據有出現相同id,相同區間長度.
譬如: id=a 就有 2 3 4  6 7 8 ; id=c 就有 1 2 4 5 7 8

你的意思是: 如果出現相同id,相同區間長度,則查詢時間最大的那個區間?
[其他解释]
如果你給的時間點有出現 相同id,相同區間長度的話 那怎麼辦?
[其他解释]
回溯,连续的1区间

不会有你说的那种情况。
[其他解释]
 已经 可以确定一个时间点,比如 9:05 或者 9:07 这样子的终点 ,

回溯 找出 连续是1 的最长区间,而且一定保证是唯一的一个 

比如 给出 9:05这个时间点,  b 9:01 9:05  与 d 9:01 9:05 长度为5 ,但是重合,所以全部排除. 
给出 9:07 这个时间点,  最长的区间是 e 9:04 9:07,没有重合的。

所以 得出 e 9:04 9:07


[其他解释]
USE test
go
 
--if object_id('t1') is not null 
--  drop table t1
--Go
--Create table t1([id] nvarchar(1),[num] nvarchar(1),[time] datetime)
--Insert into t1


--Select N'a',N'0','9:01'
--Union all Select N'a',N'1','9:02'
--Union all Select N'a',N'1','9:03'
--Union all Select N'a',N'1','9:04'
--Union all Select N'a',N'0','9:05'
--Union all Select N'a',N'1','9:06'
--Union all Select N'a',N'1','9:07'
--Union all Select N'a',N'1','9:08'
--Union all Select N'b',N'1','9:01'
--Union all Select N'b',N'1','9:02'
--Union all Select N'b',N'1','9:03'
--Union all Select N'b',N'1','9:04'
--Union all Select N'b',N'1','9:05'
--Union all Select N'b',N'0','9:06'
--Union all Select N'b',N'1','9:07'
--Union all Select N'b',N'1','9:08'
--Union all Select N'c',N'1','9:01'
--Union all Select N'c',N'1','9:02'
--Union all Select N'c',N'0','9:03'
--Union all Select N'c',N'1','9:04'
--Union all Select N'c',N'1','9:05'
--Union all Select N'c',N'0','9:06'
--Union all Select N'c',N'1','9:07'
--Union all Select N'c',N'1','9:08'
--Union all Select N'd',N'1','9:01'
--Union all Select N'd',N'1','9:02'
--Union all Select N'd',N'1','9:03'
--Union all Select N'd',N'1','9:04'
--Union all Select N'd',N'1','9:05'
--Union all Select N'd',N'0','9:06'
--Union all Select N'd',N'0','9:07'
--Union all Select N'd',N'1','9:08'
--Union all Select N'e',N'1','9:01'
--Union all Select N'e',N'0','9:02'
--Union all Select N'e',N'0','9:03'
--Union all Select N'e',N'1','9:04'
--Union all Select N'e',N'1','9:05'
--Union all Select N'e',N'1','9:06'
--Union all Select N'e',N'1','9:07'
--Union all Select N'e',N'0','9:08'
 
 
DECLARE @timestamp NVARCHAR(4)

SET @timestamp='9:07'


--create #1
IF object_id('tempdb..#1')IS NOT NULL
    DROP TABLE #1
SELECT
        a.id,b.num,b.time,CONVERT(INT,0) AS count_id
    INTO #1
    FROM t1 AS a
INNER JOIN t1 AS b ON a.id=b.id AND b.time<=@timestamp AND b.time>ISNULL((SELECT MAX(time) FROM t1 AS x WHERE x.id=b.id AND x.time<=@timestamp AND x.num=0),'')
    WHERE a.time<=@timestamp
AND EXISTS(SELECT 1 FROM t1 AS x WHERE x.id=a.id AND x.time=@timestamp AND x.num=1)
GROUP BY a.id,b.num,b.time

UPDATE a
SET count_id=(SELECT COUNT(id) FROM #1 WHERE id=a.id)
FROM #1 AS a



SELECT * FROM #1 AS a

WHERE NOT EXISTS(SELECT 1 FROM #1 AS x
WHERE a.id<>x.id AND count_id>a.count_id
)
AND NOT EXISTS(SELECT 1 FROM #1 AS x
WHERE a.id<>x.id AND x.count_id=a.count_id
)

DECLARE @tmp NVARCHAR(50),@Result NVARCHAR(50)

热点排行