如何分割数据,总和为100 我应该根据总值为100的日期插入数据 样品: http://prntscr.com/6ak0ji
答案 0 :(得分:0)
CREATE TABLE [dbo].[tmp_event_with_location] (
[event_id] bigint NOT NULL,
[vehicle_id] int NULL,
[position_id] bigint NULL,
[date_time] datetime NULL,
[event_type] smallint NULL,
[object_id] int NULL,
[x] int NULL,
[y] int NULL,
[duration] int NULL,
[description] varchar(250) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[speed] int NULL,
[speed_limit] int NULL,
[location_id] int NULL,
[odometer] int NULL,
[trip_odometer] int NULL,
[street_name] nvarchar(50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[location_name] nvarchar(50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[kecamatan] nvarchar(50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[kabupaten] nvarchar(50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[vehicle_name] varchar(30) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[geofence_code] varchar(20) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[geofence_name] varchar(50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[geofence_type] varchar(30) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[check_point_name] varchar(50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[site_name] varchar(50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[site_code] varchar(50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[site_type] varchar(50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[route_name] varchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[route_code] varchar(20) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[event_type_desc] varchar(30) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[driver_name] varchar(50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[engine] bit NULL,
[stop_time_limit] int NULL,
CONSTRAINT [tmp_event_with_location_pk_tmp_event_with_location] PRIMARY KEY CLUSTERED ([event_id])
WITH (
PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF, STATISTICS_NORECOMPUTE = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
ON [PRIMARY]
GO
CREATE TABLE [dbo].[drum_duration] (
[drum_id] int IDENTITY(1, 1) NOT NULL,
[member_id] int NULL,
[vehicle_id] int NULL,
[vehicle_number] varchar(20) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[alert_limit] int NULL,
[alert_email] varchar(30) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[sensor_start_date] datetime NULL,
[drum_date] datetime NULL,
[duration] int NULL,
[total_duration] int NULL,
[create_date] datetime NULL,
[create_by] int NULL,
[note] varchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
PRIMARY KEY CLUSTERED ([drum_id])
WITH (
PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF, STATISTICS_NORECOMPUTE = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
ON [PRIMARY]
GO
程序:
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE dbo.Aprocedure7
AS
BEGIN
--------------------------------------------------------------------------------
/*
table to test
*/
DECLARE @tmp_drum table
(
vehicle_id int ,
alert_limit int,
drum_date datetime ,
from_date datetime ,
last_drum_date datetime ,
total_duration int,
duration int ,
note varchar (100)
)
insert @tmp_drum(vehicle_id , alert_limit,drum_date,from_date,total_duration )
select dd.vehicle_id,dd.alert_limit, dd.drum_date,from_date= case when dd.drum_date is null then dd.sensor_start_date
else dd.drum_date end,
dd.total_duration
from drum_duration dd
--------------------------------------------------------------------------------
/*
get data
*/
DECLARE @tmp_table1 TABLE
(
vehicle_id int,
date_time datetime,
event_type int,
alert_limit int,
drum_date datetime,
myOrder int
)
insert @tmp_table1( vehicle_id ,date_time ,event_type ,alert_limit,drum_date,myOrder )
select b.vehicle_id, b.date_time, b.event_type, d.alert_limit,d.drum_date,
ROW_NUMBER() OVER (ORDER BY b.date_time) myOrder
from tmp_event_with_location b
inner join @tmp_drum d on d.vehicle_id =b.vehicle_id
where b.date_time >=d.from_date
and b.engine=1 and b.event_type in(68,69)
--------------------------------------------------------------------------------
/*
get the duration of the date
*/
DECLARE @tmp_table2 TABLE
(
vehicle_id int,
date_time datetime,
event_type int,
datetime_2 datetime,
event_type2 int,
alert_limit int,
drum_date datetime,
duration int --,
-- runing_total int
)
insert @tmp_table2 ( vehicle_id , date_time , event_type , datetime_2 ,
event_type2, alert_limit,drum_date, duration )
select
m.vehicle_id,
m.date_time,
m.event_type,
next.date_time as datetime_2,
next.event_type as event_type2,
m.alert_limit,
m.drum_date,
convert(int,datediff(minute,m.date_time,next.date_time))as duration--sum row by date
-- sum(convert(int,datediff(minute,m.date_time,next.date_time))) over(order by m.date_time rows between unbounded preceding and current row) AS runing_total
from @tmp_table1 as m
outer apply
(
select TOP 1 next.vehicle_id, next.date_time, next.event_type
from @tmp_table1 as next
where next.myOrder > m.myOrder and next.event_type = 68 and isnull((select event_type from @tmp_table1 prev where prev.myOrder +1 = next.myOrder),69) = 69
order by next.date_time asc
) as next
where m.event_type = 69 and ISNULL((select event_type from @tmp_table1 prev where prev.myOrder+1 = m.myOrder),68) = 68
and next.vehicle_id =m.vehicle_id
--------------------------------------------------------------------------------
/*
get the sum of the duration of the next column
*/
DECLARE @tmp_table3 TABLE
(
vehicle_id int,
date_time datetime,
event_type int,
datetime_2 datetime,
event_type2 int,
alert_limit int,
drum_date datetime,
duration int ,
runing_total int
)
insert @tmp_table3 ( vehicle_id , date_time , event_type , datetime_2 , event_type2, alert_limit,drum_date, duration, runing_total )
select
n.vehicle_id,
n.date_time,
n.event_type,
n.datetime_2,
n.event_type2,
n.alert_limit,
n.drum_date,
n.duration,
(select cast(sum(duration) as char(50)) from @tmp_table2
where datetime_2 <=n.datetime_2 and vehicle_id =n.vehicle_id) as runing_total -- ? sum duration nex row
from @tmp_table2 as n
group by
n.vehicle_id,
n.date_time,
n.event_type,
n.datetime_2,
n.event_type2,
n.alert_limit,
n.drum_date,
n.duration
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
/*
main cursor
*/
SET NOCOUNT ON
DECLARE @c_vehicle_id int , @c_datetime_2 datetime,@alert_limit int, @c_runing_total int
DECLARE CURSOR_RUN CURSOR FOR
select t2.vehicle_id,t2.datetime_2, t2.alert_limit ,t2.runing_total
from @tmp_table3 as t2
order by t2.vehicle_id,t2.datetime_2
OPEN CURSOR_RUN
FETCH NEXT FROM CURSOR_RUN INTO @c_vehicle_id , @c_datetime_2 ,@alert_limit, @c_runing_total
WHILE (@@FETCH_STATUS=0)
BEGIN
print @c_vehicle_id
IF(@c_runing_total<=@alert_limit)
BEGIN
update @tmp_drum set
last_drum_date= @c_datetime_2,
duration =@c_runing_total ,
--total_duration= total_duration + @c_runing_total ,
note= case when @c_runing_total <= alert_limit then '-' else 'its duration exceeds the specified limit alerts'end
where vehicle_id =@c_vehicle_id
and @c_runing_total<=@alert_limit
and drum_date is not null --? calculated from the date of drum_date and do not exceed the limit alerts
END
ELSE
BEGIN
update @tmp_drum set
last_drum_date= @c_datetime_2,
duration =@c_runing_total ,
--total_duration= total_duration + @c_runing_total ,
note= case when @c_runing_total <= alert_limit then '-' else 'counted from the start of pairs of sensors'end
where vehicle_id =@c_vehicle_id
and @c_runing_total>=@alert_limit --
and drum_date is null --? sensors installed from the beginning and over the limit alerts
END
FETCH NEXT FROM CURSOR_RUN INTO @c_vehicle_id , @c_datetime_2 ,@alert_limit, @c_runing_total
END
CLOSE CURSOR_RUN
DEALLOCATE CURSOR_RUN
SET NOCOUNT OFF
select * from @tmp_table3
select * from @tmp_drum
END