2010-04-21 4 views
4

У меня есть эта вещь, которую мне нужно сделать, и некоторые советы будут очень признательны. У меня есть таблица SQL-сервера с некоторыми телефонными звонками. Для каждого телефонного звонка у меня есть время начала и окончания.Вопросы, связанные с SQL Server

Что мне нужно сделать: хранимая процедура, которая в течение определенного периода времени, скажем, 5 часов с интервалом x, позволяет сказать, что 2 минуты возвращает количество подключенных вызовов.

Something like: 

Interval         Nr of Calls Connected 
01-01-2010 12:00:00 - 01-01-2010 12:05:00 30 
01-01-2010 12:05:01 - 01-01-2010 12:10:00 10 
............. 

Какой будет самый быстрый способ сделать это? Спасибо за вашу помощь

+1

Какая версия SQL Server? – ChaosPandion

+0

Вы хотите показать результаты для временных интервалов, которые имеют как минимум 1 вызов? или показать или интервалы, даже если есть 0 вызовов? –

+1

каждый интервал, даже если в нем нет вызовов. Sql server 2005 – stefan

ответ

2

Это будет работать с интервалами, которые имеют вызовы ...

Declare @datetimestart datetime 
Declare @interval int 
Set @datetimestart = '2009-01-01 12:00:00' 
Set @interval = 5 --in minutes 

Select 
    [start_interval], [end_interval] , count([start_interval]) as [calls] 
From 
    (
    Select 
    DateAdd(Minute,Floor(DateDiff(Minute,@datetimestart,[date])/@interval)*@interval 
,@datetimestart) , 
    DateAdd(Minute,@interval + Floor(DateDiff(Minute,@datetimestart,[date])/@interval)*@interval 
,@datetimestart) 
    From yourTable 
) As W([start_interval],[end_interval]) 
group by [start_interval], [end_interval] 

Это будет работать для всех интервалов, независимо от количества вызовов ..

Declare @datetimestart datetime, @datetimeend datetime, @datetimecurrent datetime 
Declare @interval int 
Set @datetimestart = '2009-01-01 12:00:00' 
Set @interval = 10 
Set @datetimeend = (Select max([date]) from yourtable) 

SET @datetimecurrent = @datetimestart 

declare @temp as table ([start_interval] datetime, [end_interval] datetime) 

while @datetimecurrent < @datetimeend 
BEGIN 
    insert into @temp select (@datetimecurrent), dateAdd(minute, @interval, @datetimecurrent) 
    set @datetimecurrent = dateAdd(minute, @interval, @datetimecurrent) 
END 

Select 
    * 
From 
    (
    Select 
     [start_interval],[end_interval], count(d.[start_time]) 
    From @temp t left join yourtable d on d.[start_time] between t.[start_interval] and t.[end_interval] 
) As W([start_interval],[end_interval], [calls]) 
+0

Hi Gaby, Благодарим за помощь. Я просмотрел последний запрос, чтобы включить все интервалы, и это От @temp t слева присоединитесь к таблице d на d. [Start_time] между t. [Start_interval] и t. [End_interval] Принимает во внимание только начатые звонки в этом интервале и опускает вызовы с начальным интервалом end end. Эти звонки по-прежнему связаны, и они должны быть включены – stefan

+0

@stefan, я вижу ... так что вызов можно было подсчитать за несколько интервалов, верно? –

+0

@stefan, если при этом следующее должно охватывать все случаи (* i think *) 'on ((d. ​​[Start_time] между t. [Start_interval] и t. [End_interval]) ИЛИ (d. [End_time] между t. [start_interval] и t. [end_interval]) ИЛИ (d. [start_time] t. [end_interval]) ' –

0

Как об этом подходе:

select Year(StartTime) as Year, Month(StartTime) as Month, Day(StartTime) as Day, datepart(hh, StartTime) as Hour, datepart(mm, StartTime)/2 as TwoMinuteSegment, count(*) 
from MyTable 
where StartDate between '01-01-2010 12:00:00' and '01-01-2010 17:00:00' 
group by Year(StartTime), Month(StartTime), Day(StartTime), datepart(hh, StartTime), datepart(mm, StartTime)/2 
1

Я Altered пример Габи немного, чтобы сделать, что вы ожидали

Declare @datetimeend datetime 
,@datetimecurrent datetime 
,@interval int 
Set @interval = 10 
Set @datetimeend = (Select max([end_time]) from Calls) 
SET @datetimecurrent = '2010-04-17 14:20:00' 

declare @temp as table ([start_interval] datetime, [end_interval] datetime) 

while @datetimecurrent < @datetimeend 
BEGIN 
    insert into @temp select (@datetimecurrent), dateAdd(minute, @interval, @datetimecurrent) 
    set @datetimecurrent = dateAdd(minute, @interval, @datetimecurrent) 
END 

Select 
    [start_interval],[end_interval], count(d.id) [COUNT] 
From @temp t 
left join Calls d on 
    d.end_time >= t.start_interval 
AND d.start_time <= t.end_interval 
GROUP BY [start_interval],[end_interval] 

использовал это, чтобы создать таблицу и заполнить его

CREATE TABLE dbo.Calls 
    (
    id int NOT NULL IDENTITY (1, 1), 
    start_time datetime NOT NULL, 
    end_time datetime NULL, 
    caller nvarchar(50) NULL, 
    receiver nvarchar(50) NULL 
    ) ON [PRIMARY] 
GO 
ALTER TABLE dbo.Calls ADD CONSTRAINT 
    PK_Calls PRIMARY KEY CLUSTERED 
    (
    id 
    ) ON [PRIMARY] 

GO 

DECLARE @I INT 
SET @I = 0 
WHILE @I < 100 
BEGIN 
INSERT INTO Calls 
(start_time, end_time) 
select 
DATEADD(HOUR,[email protected],DATEADD(MINUTE,-10,GETDATE())) 
,DATEADD(HOUR,[email protected],DATEADD(MINUTE,-9,GETDATE())) 
UNION 
select 
DATEADD(HOUR,[email protected],DATEADD(MINUTE,-9,GETDATE())) 
,DATEADD(HOUR,[email protected],DATEADD(MINUTE,-8,GETDATE())) 
UNION 
select 
DATEADD(HOUR,[email protected],DATEADD(MINUTE,-8,GETDATE())) 
,DATEADD(HOUR,[email protected],DATEADD(MINUTE,-7,GETDATE())) 
UNION 
select 
DATEADD(HOUR,[email protected],DATEADD(MINUTE,-7,GETDATE())) 
,DATEADD(HOUR,[email protected],DATEADD(MINUTE,-6,GETDATE())) 
UNION 
select 
DATEADD(HOUR,[email protected],DATEADD(MINUTE,-6,GETDATE())) 
,DATEADD(HOUR,[email protected],DATEADD(MINUTE,-5,GETDATE())) 
UNION 
SELECT 
DATEADD(HOUR,[email protected],DATEADD(MINUTE,-5,GETDATE())) 
,DATEADD(HOUR,[email protected],DATEADD(MINUTE,-4,GETDATE())) 
UNION 
select 
DATEADD(HOUR,[email protected],DATEADD(MINUTE,-4,GETDATE())) 
,DATEADD(HOUR,[email protected],DATEADD(MINUTE,-3,GETDATE())) 
UNION 
select 
DATEADD(HOUR,[email protected],DATEADD(MINUTE,-3,GETDATE())) 
,DATEADD(HOUR,[email protected],DATEADD(MINUTE,-2,GETDATE())) 
UNION 
select 
DATEADD(HOUR,[email protected],DATEADD(MINUTE,-2,GETDATE())) 
,DATEADD(HOUR,[email protected],DATEADD(MINUTE,-1,GETDATE())) 
UNION 
select 
DATEADD(HOUR,[email protected],DATEADD(MINUTE,-1,GETDATE())) 
,DATEADD(HOUR,[email protected],DATEADD(MINUTE,-0,GETDATE())); 
SET @I = @I + 1 
END  

Выполнено в SQL Server 2008 , но скрипт будет работать в другой версии сий

1

Я хотел бы использовать a Numbers, чтобы получить временные интервалы, а затем подсчитать все вызовы, которые перекрывают интервал:

SELECT Intervals.IntervalStart 
    ,Intervals.IntervalEnd 
    ,COUNT(*) 
FROM (
    SELECT DATEADD(MINUTE, Numbers * 2, @StartTime) AS IntervalStart 
     ,DATEADD(MINUTE, (Numbers + 1) * 2, @StartTime) AS IntervalEnd 
    FROM Numbers 
    WHERE Numbers BETWEEN 0 AND (5 * 60/2) 
) AS Intervals 
LEFT JOIN Calls 
    ON Calls.CallEnd >= Intervals.IntervalStart 
     AND Calls.CallStart < Intervals.IntervalEnd 
GROUP BY Intervals.IntervalStart 
    ,Intervals.IntervalEnd 

Чтобы получить пустые интервалы, вам понадобится LEFT JOIN к этому из другой производной таблицы «Интервалы».

Смежные вопросы