22,209
社区成员
发帖
与我相关
我的任务
分享
create function [dbo].[getnums]
(@n int)
returns table as
return
with t1 as(select 1 n union all select 1)
,t2 as(select 1 n from t1,t1 a,t1 b,t1 c)
,t3 as(select 1 n from t2,t2 a,t2 b,t2 c)
,t4 as(select 1 n from t3,t3 a)
select top(@n) row_number()over(order by(select 1)) n from t4
order by n
declare @tab table([观测站编号] nvarchar(33),[观测站名称] nvarchar(25),[行驶方向] nvarchar(22),[观测日期] Date,[小时] int,[分钟] int)
Insert @tab
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',16,30 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',16,40 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',17,0 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',17,55 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',18,25 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',19,30 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',19,50 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',20,20 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',20,55 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',21,25 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',22,50 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',23,20 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',23,55 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',24,25 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',24,45 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',1,15 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',2,5 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',2,40 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',3,10 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',3,45 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',4,35 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',5,5 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',5,40
--[观测日期] Date,[小时] int,[分钟] int)
if object_id('tempdb..#t_0')is not null drop table #t_0
;with
t as (select *,dt=(datediff(d,0,观测日期)*24+[小时])*12+[分钟]/5 from @tab)
,t1 as (select dt1=min(dt),dt2=max(dt) from t)
,t2 as (select dt=(dt1+n-1) from t1 cross apply getnums((dt2-dt1)+1))
,t3 as (select t2.* from t2 left join t on t2.dt =t.dt where t.dt is null)
,t4 as (select rid=row_number()over(order by dt),dt from t3)
select
dt=dateadd(minute,dt*5,0)
,ct=count(*)over(partition by dt-rid)
into #t_0
from t4
if object_id('tempdb..#t_1')is not null drop table #t_1
if object_id('tempdb..#t_2')is not null drop table #t_2
if object_id('tempdb..#t_3')is not null drop table #t_3
select * into #t_1 from #t_0 where ct=1
select * into #t_2 from #t_0 where ct in(2,3)
select * into #t_3 from #t_0 where ct>3
select * from #t_1
select * from #t_2
select * from #t_3
use Tempdb
go
--> --> 听雨停了-->测试数据
if not object_id(N'Tempdb..#tab') is null
drop table #tab
Go
Create table #tab([观测站编号] nvarchar(33),[观测站名称] nvarchar(25),[行驶方向] nvarchar(22),[观测日期] Date,[小时] int,[分钟] int)
Insert #tab
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',16,30 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',17,0 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',17,55 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',18,25 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',19,30 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',19,50 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',20,20 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',20,55 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',21,25 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',22,50 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',23,20 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',23,55 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',24,25 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',24,45 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',1,15 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',2,5 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',2,40 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',3,10 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',3,45 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',4,35 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',5,5 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',5,40
--建立三个存放数据的表A B C
SELECT * into #tabA FROM #tab WHERE 1<>1
SELECT * into #tabB FROM #tab WHERE 1<>1
SELECT * into #tabC FROM #tab WHERE 1<>1
----测试数据结束
--建立一个数字辅助表
CREATE TABLE num(
number INT IDENTITY(0,1),
id INT
)
--插入数据进去
INSERT INTO num
SELECT number FROM [master]..spt_values WHERE TYPE='p'
UNION ALL
SELECT number FROM [master]..spt_values WHERE TYPE='p'
UNION ALL
SELECT number FROM [master]..spt_values WHERE TYPE='p'
UNION ALL
SELECT number FROM [master]..spt_values WHERE TYPE='p'
UNION ALL
SELECT number FROM [master]..spt_values WHERE TYPE='p'
SELECT number FROM num
/*
* 你这个表的数据肯定很早以前就开始有了,一直到今天,数据量肯定好大。而且每个观测站最初的第一条数据
* 肯定不可能就是某个月1号的零点零分开始的,因此当你需要计算表数据产生第一个月中丢掉的数据的时候
* 必然是从每个观测站第一条记录的时间开始算起,到这个月月底结束。
*
* 例如:你的数据从2016-01-05开始,到今天2017-11-30结束
* 如果按月计算就是这样的日期段:
* 2016-01-05----2016-01-31(1月1号到5号开始前的日期都不能算,因为第一条记录才刚产生呢,因此之前的不能算是丢掉的)
* 2016-02-01----2016-02-29(2016年是闰年,假如2016年的29号你的表中没有记录,那么这一天都丢掉了
* 如果你按2月28天算,那丢掉的一天数据就查询不到了,因此需要区分是否闰年)
* 2016-03-01----2016-03-31
* 2016-04-01----2016-04-30
* ...........................
*
* */
--EXEC INSERT_data '2016','08',0,0
CREATE PROC insert_data
@year VARCHAR(20),
@month VARCHAR(20),
@ifbegin_month BIT =1, --默认为1代表是(是否从每月1号计算起)
@ifend_month BIT =1 --默认为1代表是(是否计算到每月的月底)
AS
BEGIN
DECLARE @maxnum INT
--判断是否闰年
IF (RIGHT(@year,2)='00' AND @year%400=0) OR ( @year%4=0)
BEGIN
SELECT @maxnum=CASE when @month IN ('01','03','05','07','08','10','12') THEN 31*288-1
WHEN @month IN ('04','06','09','11') THEN 30*288-1
ELSE 29*288-1
END
END
ELSE
BEGIN
SELECT @maxnum=CASE when @month IN ('01','03','05','07','08','10','12') THEN 31*288-1
WHEN @month IN ('04','06','09','11') THEN 30*288-1
ELSE 28*288-1
END
END
PRINT @maxnum
Select *,DAY(观测日期) as day,(DAY(观测日期)-1)*288+分钟/5+(小时-1)*12 as num
INTO #tab1
from #tab
WHERE YEAR(观测日期)=@year and month(观测日期)=@month
SELECT DISTINCT 观测站编号,观测站名称,行驶方向,min(num) as minnum,max(num) as maxnum
INTO #tab2
FROM #tab1
GROUP BY 观测站编号,观测站名称,行驶方向
SELECT a.观测站编号,a.观测站名称,a.行驶方向,b.number
INTO #tab3
FROM #tab2 a,
num b
WHERE b.number BETWEEN (case @ifbegin_month when 1 then 0 else a.minnum end)
AND (case @ifend_month when 1 then @maxnum else a.maxnum end)
SELECT *
INTO #tab4
FROM #tab3
EXCEPT
SELECT 观测站编号,观测站名称,行驶方向,num
FROM #tab1
SELECT *,
@year+'-'+@month+'-'+RIGHT('00'+cast(number/288+1 AS VARCHAR(20)),2) AS 观测日期,
number%288/12+1 as 小时,
number%288%12*5 as 分钟,
number-ROW_NUMBER() OVER(PARTITION BY 观测站编号,观测站名称,行驶方向 order by number)as rn
INTO #tab5
FROM #tab4
SELECT rn,COUNT(1) AS cnt
INTO #tab6
FROM #tab5
GROUP BY rn
----丢失一条时插入#tabA表中
--INSERT INTO #tabA(观测站编号,观测站名称,行驶方向,观测日期,小时,分钟)
SELECT 观测站编号,观测站名称,行驶方向,观测日期,小时,分钟 FROM #tab5 a
INNER JOIN #tab6 b ON a.rn=b.rn
WHERE b.cnt=1
----丢失两条时插入#tabB表中
--INSERT INTO #tabB(观测站编号,观测站名称,行驶方向,观测日期,小时,分钟)
SELECT 观测站编号,观测站名称,行驶方向,观测日期,小时,分钟 FROM #tab5 a
INNER JOIN #tab6 b ON a.rn=b.rn
WHERE b.cnt=2
----丢失三条或以上时插入#tabC表中
--INSERT INTO #tabC(观测站编号,观测站名称,行驶方向,观测日期,小时,分钟)
SELECT 观测站编号,观测站名称,行驶方向,观测日期,小时,分钟 FROM #tab5 a
INNER JOIN #tab6 b ON a.rn=b.rn
WHERE b.cnt>=3
--清空临时表,以便下次使用
TRUNCATE TABLE #tab1
TRUNCATE TABLE #tab2
TRUNCATE TABLE #tab3
TRUNCATE TABLE #tab4
TRUNCATE TABLE #tab5
TRUNCATE TABLE #tab6
END
use Tempdb
go
--> --> 听雨停了-->测试数据
if not object_id(N'Tempdb..#tab') is null
drop table #tab
Go
Create table #tab([观测站编号] nvarchar(33),[观测站名称] nvarchar(25),[行驶方向] nvarchar(22),[观测日期] Date,[小时] int,[分钟] int)
Insert #tab
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',16,30 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',17,0 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',17,55 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',18,25 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',19,30 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',19,50 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',20,20 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',20,55 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',21,25 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',22,50 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',23,20 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',23,55 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',24,25 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',24,45 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',1,15 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',2,5 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',2,40 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',3,10 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',3,45 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',4,35 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',5,5 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',5,40
--建立三个存放数据的表A B C
SELECT * into #tabA FROM #tab WHERE 1<>1
SELECT * into #tabB FROM #tab WHERE 1<>1
SELECT * into #tabC FROM #tab WHERE 1<>1
----测试数据结束
--建立一个数字辅助表
CREATE TABLE num(
number INT IDENTITY(0,1),
id INT
)
--插入数据进去
INSERT INTO num
SELECT number FROM [master]..spt_values WHERE TYPE='p'
UNION ALL
SELECT number FROM [master]..spt_values WHERE TYPE='p'
UNION ALL
SELECT number FROM [master]..spt_values WHERE TYPE='p'
UNION ALL
SELECT number FROM [master]..spt_values WHERE TYPE='p'
UNION ALL
SELECT number FROM [master]..spt_values WHERE TYPE='p'
SELECT number FROM num
/*
* 你这个表的数据肯定很早以前就开始有了,一直到今天,数据量肯定好大。而且每个观测站最初的第一条数据
* 肯定不可能就是某个月1号的零点零分开始的,因此当你需要计算表数据产生第一个月中丢掉的数据的时候
* 必然是从每个观测站第一条记录的时间开始算起,到这个月月底结束。
*
* 例如:你的数据从2016-01-05开始,到今天2017-11-30结束
* 如果按月计算就是这样的日期段:
* 2016-01-05----2016-01-31(1月1号到5号开始前的日期都不能算,因为第一条记录才刚产生呢,因此之前的不能算是丢掉的)
* 2016-02-01----2016-02-29(2016年是闰年,假如2016年的29号你的表中没有记录,那么这一天都丢掉了
* 如果你按2月28天算,那丢掉的一天数据就查询不到了,因此需要区分是否闰年)
* 2016-03-01----2016-03-31
* 2016-04-01----2016-04-30
* ...........................
*
* */
--EXEC INSERT_data '2016','08',0,0
CREATE PROC insert_data
@year VARCHAR(20),
@month VARCHAR(20),
@ifbegin_month BIT =1, --默认为1代表是(是否从每月1号计算起)
@ifend_month BIT =1 --默认为1代表是(是否计算到每月的月底)
AS
BEGIN
DECLARE @maxnum INT
--判断是否闰年
IF (RIGHT(@year,2)='00' AND @year%400=0) OR ( @year%4=0)
BEGIN
SELECT @maxnum=CASE when @month IN ('01','03','05','07','08','10','12') THEN 31*288-1
WHEN @month IN ('04','06','09','11') THEN 30*288-1
ELSE 29*288-1
END
END
ELSE
BEGIN
SELECT @maxnum=CASE when @month IN ('01','03','05','07','08','10','12') THEN 31*288-1
WHEN @month IN ('04','06','09','11') THEN 30*288-1
ELSE 28*288-1
END
END
PRINT @maxnum
Select *,DAY(观测日期) as day,(DAY(观测日期)-1)*288+分钟/5+(小时-1)*12 as num
INTO #tab1
from #tab
WHERE YEAR(观测日期)=@year and month(观测日期)=@month
SELECT DISTINCT 观测站编号,观测站名称,行驶方向,min(num) as minnum,max(num) as maxnum
INTO #tab2
FROM #tab1
GROUP BY 观测站编号,观测站名称,行驶方向
SELECT a.观测站编号,a.观测站名称,a.行驶方向,b.number
INTO #tab3
FROM #tab2 a,
num b
WHERE b.number BETWEEN (case @ifbegin_month when 1 then 0 else a.minnum end)
AND (case @ifend_month when 1 then @maxnum else a.maxnum end)
SELECT *
INTO #tab4
FROM #tab3
EXCEPT
SELECT 观测站编号,观测站名称,行驶方向,num
FROM #tab1
SELECT *,
@year+'-'+@month+'-'+RIGHT('00'+cast(number/288+1 AS VARCHAR(20)),2) AS 观测日期,
number%288/12+1 as 小时,
number%288%12*5 as 分钟,
number-ROW_NUMBER() OVER(PARTITION BY 观测站编号,观测站名称,行驶方向 order by number)as rn
INTO #tab5
FROM #tab4
SELECT rn,COUNT(1) AS cnt
INTO #tab6
FROM #tab5
GROUP BY rn
----丢失一条时插入#tabA表中
--INSERT INTO #tabA(观测站编号,观测站名称,行驶方向,观测日期,小时,分钟)
SELECT 观测站编号,观测站名称,行驶方向,观测日期,小时,分钟 FROM #tab5 a
INNER JOIN #tab6 b ON a.rn=b.rn
WHERE b.cnt=1
----丢失两条时插入#tabB表中
--INSERT INTO #tabB(观测站编号,观测站名称,行驶方向,观测日期,小时,分钟)
SELECT 观测站编号,观测站名称,行驶方向,观测日期,小时,分钟 FROM #tab5 a
INNER JOIN #tab6 b ON a.rn=b.rn
WHERE b.cnt=2
----丢失三条或以上时插入#tabC表中
--INSERT INTO #tabC(观测站编号,观测站名称,行驶方向,观测日期,小时,分钟)
SELECT 观测站编号,观测站名称,行驶方向,观测日期,小时,分钟 FROM #tab5 a
INNER JOIN #tab6 b ON a.rn=b.rn
WHERE b.cnt>=3
--清空临时表,以便下次使用
TRUNCATE TABLE #tab1
TRUNCATE TABLE #tab2
TRUNCATE TABLE #tab3
TRUNCATE TABLE #tab4
TRUNCATE TABLE #tab5
TRUNCATE TABLE #tab6
END
use Tempdb
go
--> --> 听雨停了-->测试数据
if not object_id(N'Tempdb..#tab') is null
drop table #tab
Go
Create table #tab([观测站编号] nvarchar(33),[观测站名称] nvarchar(25),[行驶方向] nvarchar(22),[观测日期] Date,[小时] int,[分钟] int)
Insert #tab
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',16,30 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',17,0 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',17,55 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',18,25 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',19,30 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',19,50 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',20,20 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',20,55 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',21,25 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',22,50 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',23,20 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',23,55 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',24,25 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/3',24,45 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',1,15 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',2,5 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',2,40 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',3,10 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',3,45 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',4,35 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',5,5 union all
select N'G25L372130208',N'丰润收费站',N'上行','2016/8/4',5,40
--建立三个存放数据的表A B C
SELECT * into #tabA FROM #tab WHERE 1<>1
SELECT * into #tabB FROM #tab WHERE 1<>1
SELECT * into #tabC FROM #tab WHERE 1<>1
----测试数据结束
--建立一个数字辅助表
CREATE TABLE num(
number INT IDENTITY(0,1),
id INT
)
--插入数据进去
INSERT INTO num
SELECT number FROM [master]..spt_values WHERE TYPE='p'
UNION ALL
SELECT number FROM [master]..spt_values WHERE TYPE='p'
UNION ALL
SELECT number FROM [master]..spt_values WHERE TYPE='p'
UNION ALL
SELECT number FROM [master]..spt_values WHERE TYPE='p'
UNION ALL
SELECT number FROM [master]..spt_values WHERE TYPE='p'
SELECT number FROM num
/*
* 你这个表的数据肯定很早以前就开始有了,一直到今天,数据量肯定好大。而且每个观测站最初的第一条数据
* 肯定不可能就是某个月1号的零点零分开始的,因此当你需要计算表数据产生第一个月中丢掉的数据的时候
* 必然是从每个观测站第一条记录的时间开始算起,到这个月月底结束。
*
* 例如:你的数据从2016-01-05开始,到今天2017-11-30结束
* 如果按月计算就是这样的日期段:
* 2016-01-05----2016-01-31(1月1号到5号开始前的日期都不能算,因为第一条记录才刚产生呢,因此之前的不能算是丢掉的)
* 2016-02-01----2016-02-29(2016年是闰年,假如2016年的29号你的表中没有记录,那么这一天都丢掉了
* 如果你按2月28天算,那丢掉的一天数据就查询不到了,因此需要区分是否闰年)
* 2016-03-01----2016-03-31
* 2016-04-01----2016-04-30
* ...........................
*
* */
--EXEC INSERT_data '2016','08',0,0
CREATE PROC insert_data
@year VARCHAR(20),
@month VARCHAR(20),
@ifbegin_month BIT =1, --默认为1代表是(是否从每月1号计算起)
@ifend_month BIT =1 --默认为1代表是(是否计算到每月的月底)
AS
BEGIN
DECLARE @maxnum INT
--判断是否闰年
IF (RIGHT(@year,2)='00' AND @year%400=0) OR ( @year%4=0)
BEGIN
SELECT @maxnum=CASE when @month IN ('01','03','05','07','08','10','12') THEN 31*288-1
WHEN @month IN ('04','06','09','11') THEN 30*288-1
ELSE 29*288-1
END
END
ELSE
BEGIN
SELECT @maxnum=CASE when @month IN ('01','03','05','07','08','10','12') THEN 31*288-1
WHEN @month IN ('04','06','09','11') THEN 30*288-1
ELSE 28*288-1
END
END
PRINT @maxnum
Select *,DAY(观测日期) as day,(DAY(观测日期)-1)*288+分钟/5+(小时-1)*12 as num
INTO #tab1
from #tab
WHERE YEAR(观测日期)=@year and month(观测日期)=@month
SELECT DISTINCT 观测站编号,观测站名称,行驶方向,min(num) as minnum,max(num) as maxnum
INTO #tab2
FROM #tab1
GROUP BY 观测站编号,观测站名称,行驶方向
SELECT a.观测站编号,a.观测站名称,a.行驶方向,b.number
INTO #tab3
FROM #tab2 a,
num b
WHERE b.number BETWEEN (case @ifbegin_month when 1 then 0 else a.minnum end)
AND (case @ifend_month when 1 then @maxnum else a.maxnum end)
SELECT *
INTO #tab4
FROM #tab3
EXCEPT
SELECT 观测站编号,观测站名称,行驶方向,num
FROM #tab1
SELECT *,
@year+'-'+@month+'-'+RIGHT('00'+cast(number/288+1 AS VARCHAR(20)),2) AS 观测日期,
number%288/12+1 as 小时,
number%288%12*5 as 分钟,
number-ROW_NUMBER() OVER(PARTITION BY 观测站编号,观测站名称,行驶方向 order by number)as rn
INTO #tab5
FROM #tab4
SELECT rn,COUNT(1) AS cnt
INTO #tab6
FROM #tab5
GROUP BY rn
----丢失一条时插入#tabA表中
--INSERT INTO #tabA(观测站编号,观测站名称,行驶方向,观测日期,小时,分钟)
SELECT 观测站编号,观测站名称,行驶方向,观测日期,小时,分钟 FROM #tab5 a
INNER JOIN #tab6 b ON a.rn=b.rn
WHERE b.cnt=1
----丢失两条时插入#tabB表中
--INSERT INTO #tabB(观测站编号,观测站名称,行驶方向,观测日期,小时,分钟)
SELECT 观测站编号,观测站名称,行驶方向,观测日期,小时,分钟 FROM #tab5 a
INNER JOIN #tab6 b ON a.rn=b.rn
WHERE b.cnt=2
----丢失三条或以上时插入#tabC表中
--INSERT INTO #tabC(观测站编号,观测站名称,行驶方向,观测日期,小时,分钟)
SELECT 观测站编号,观测站名称,行驶方向,观测日期,小时,分钟 FROM #tab5 a
INNER JOIN #tab6 b ON a.rn=b.rn
WHERE b.cnt>=3
--清空临时表,以便下次使用
TRUNCATE TABLE #tab1
TRUNCATE TABLE #tab2
TRUNCATE TABLE #tab3
TRUNCATE TABLE #tab4
TRUNCATE TABLE #tab5
TRUNCATE TABLE #tab6
END
SELECT COUNT(1) AS cnt,COUNT(1)/(24*12*365) AS years FROM [master].dbo.spt_values AS s1 CROSS APPLY [master].dbo.spt_values AS s2
/*
cnt years
5503716 52
*/
他分得太细了, 只有52年, 不过应该也够用了。
with cte_1
as
(select *,
dateadd(minute,[分钟],dateadd(HOUR,[小时],cast([观测日期] as datetime))) as [time]
from table),
cte_2
as
(select ROW_NUMBER() over (order by (select null)) as seq
from master..spt_values A,master..spt_values B
where A.TYPE='P' and B.type='P' and A.number<1000 and B.number<1000)
select *,
count(1) over (partition by rn_1-rn_2) as 连续次数,
case when count(1) over (partition by rn_1-rn_2)=1 then 'A'
when count(1) over (partition by rn_1-rn_2)>3 then 'C'
else 'B'
end as type
from
(select *,
case when isnull(B.time,'')='' then '0' else '1' end as symbol,
ROW_NUMBER() over (order by schedule_time) as rn_1,
ROW_NUMBER() over (partition by case when isnull(B.time,'')='' then '0' else '1' end order by schedule_time) as rn_2
from
(select DATEADD(MINUTE,(seq-1)*5,min_time) as schedule_time
from (select MIN(time) as min_time,MAX(time) as max_time from cte_1) as A
join cte_2 as B on (DATEDIFF(MINUTE,min_time,max_time)/5)+1>=B.seq) as A
left join cte_1 as B ON A.schedule_time=B.time) as A
where symbol=0
order by schedule_time
DROP TABLE #tmp
USE tempdb
GO
IF OBJECT_ID('t') IS NOT NULL DROP TABLE t
IF OBJECT_ID('b') IS NOT NULL DROP TABLE b
IF OBJECT_ID('c') IS NOT NULL DROP TABLE c
GO
CREATE TABLE t(d DATE,h INT,m INT)
CREATE TABLE b(d DATE,h INT,m INT)
CREATE TABLE c(d DATE,h INT,m INT)
--0. 插入测试数据
;WITH cte AS(
SELECT DATEADD(n,sv.number*5,'2017-08-03 16:30') AS theTime
FROM MASTER.dbo.spt_values AS sv
WHERE sv.[type]='P' AND DATEADD(n,sv.number*5,'2017-08-03 16:30')
BETWEEN '2017-08-03 16:30' AND '2017-08-04 08:40'
)
INSERT INTO t
SELECT CONVERT(CHAR(10),theTime,120),DATEPART(hour,theTime),DATEPART(minute,theTime)
FROM cte
--1. 增加完整时间计算列
ALTER TABLE t ADD fullTime AS CAST( (CONVERT(CHAR(10),d,120)+' '+CAST(h AS VARCHAR(2))+':'+CAST(m AS VARCHAR(2))) AS DATETIME)
GO
--删除部分记录
DELETE FROM t WHERE fullTime IN ('2017-08-03 16:35:00.000','2017-08-03 16:40:00.000','2017-08-03 16:45:00.000','2017-08-03 16:50:00.000')
DELETE FROM t WHERE fullTime IN ('2017-08-03 17:10:00.000','2017-08-03 17:15:00.000')
GO
/*
--先查出来看看
;WITH cte AS(
SELECT ROW_NUMBER() OVER (ORDER BY fullTime) AS rid,* FROM t
)
SELECT a.*,DATEDIFF(n,a.fullTime,b.fullTime)/5-1 AS lostData
FROM cte AS a LEFT JOIN cte AS b ON a.rid=b.rid-1
*/
IF OBJECT_ID('tempdb..#tmp') IS NOT NULL DROP TABLE #tmp
;WITH cte AS(
SELECT ROW_NUMBER() OVER (ORDER BY fullTime) AS rid,* FROM t
),cte2 AS(
SELECT a.*,CAST( (DATEDIFF(n,a.fullTime,b.fullTime)/5-1) AS INT) AS lostData
FROM cte AS a LEFT JOIN cte AS b ON a.rid=b.rid-1
)
SELECT *
INTO #tmp
FROM cte2
WHERE lostData>0
;WITH cte AS (
SELECT DATEADD(n,t.number*5,a.fullTime) AS fullTime
FROM #tmp AS a
OUTER APPLY (SELECT sv.number
FROM MASTER.dbo.spt_values AS sv WHERE sv.type='P' AND sv.number>=1 AND sv.number<=a.lostData) AS t --ON 1=1
WHERE lostData<3
)
INSERT INTO b
SELECT CONVERT(CHAR(10),fullTime,120),DATEPART(hour,fullTime),DATEPART(minute,fullTime) FROM cte
--SELECT * FROM #tmp
;WITH cte AS (
SELECT DATEADD(n,t.number*5,a.fullTime) AS fullTime
FROM #tmp AS a
OUTER APPLY (SELECT sv.number
FROM MASTER.dbo.spt_values AS sv WHERE sv.type='P' AND sv.number>=1 AND sv.number<=a.lostData) AS t --ON 1=1
WHERE lostData>=3
)
INSERT INTO c
SELECT CONVERT(CHAR(10),fullTime,120),DATEPART(hour,fullTime),DATEPART(minute,fullTime) FROM cte
SELECT * FROM b
/*
d h m
2017-08-03 17 10
2017-08-03 17 15
*/
SELECT * FROM c
/*
d h m
2017-08-03 16 35
2017-08-03 16 40
2017-08-03 16 45
2017-08-03 16 50
*/