Вопрос, связанный с SQL Server

97
8

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


Что мне нужно сделать: хранимая процедура, которая в течение определенного периода времени, скажем, 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
.............


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

спросил(а) 2010-04-21T19:10:00+04:00 10 лет, 11 месяцев назад
1
Решение
62

Я бы использовал сводную таблицу 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 для этого из другой производной таблицы "Интервалы".

ответил(а) 2010-04-21T19:44:00+04:00 10 лет, 11 месяцев назад
74

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


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])

ответил(а) 2010-04-21T19:27:00+04:00 10 лет, 11 месяцев назад
62

Я немного изменил пример Gaby Что вы ожидали


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,-@I,DATEADD(MINUTE,-10,GETDATE()))
,DATEADD(HOUR,-@I,DATEADD(MINUTE,-9,GETDATE()))
UNION
select
DATEADD(HOUR,-@I,DATEADD(MINUTE,-9,GETDATE()))
,DATEADD(HOUR,-@I,DATEADD(MINUTE,-8,GETDATE()))
UNION
select
DATEADD(HOUR,-@I,DATEADD(MINUTE,-8,GETDATE()))
,DATEADD(HOUR,-@I,DATEADD(MINUTE,-7,GETDATE()))
UNION
select
DATEADD(HOUR,-@I,DATEADD(MINUTE,-7,GETDATE()))
,DATEADD(HOUR,-@I,DATEADD(MINUTE,-6,GETDATE()))
UNION
select
DATEADD(HOUR,-@I,DATEADD(MINUTE,-6,GETDATE()))
,DATEADD(HOUR,-@I,DATEADD(MINUTE,-5,GETDATE()))
UNION
SELECT
DATEADD(HOUR,-@I,DATEADD(MINUTE,-5,GETDATE()))
,DATEADD(HOUR,-@I,DATEADD(MINUTE,-4,GETDATE()))
UNION
select
DATEADD(HOUR,-@I,DATEADD(MINUTE,-4,GETDATE()))
,DATEADD(HOUR,-@I,DATEADD(MINUTE,-3,GETDATE()))
UNION
select
DATEADD(HOUR,-@I,DATEADD(MINUTE,-3,GETDATE()))
,DATEADD(HOUR,-@I,DATEADD(MINUTE,-2,GETDATE()))
UNION
select
DATEADD(HOUR,-@I,DATEADD(MINUTE,-2,GETDATE()))
,DATEADD(HOUR,-@I,DATEADD(MINUTE,-1,GETDATE()))
UNION
select
DATEADD(HOUR,-@I,DATEADD(MINUTE,-1,GETDATE()))
,DATEADD(HOUR,-@I,DATEADD(MINUTE,-0,GETDATE()));
SET @I = @I + 1
END


Выполнено в SQL Server 2008
но script будет работать в других версиях

ответил(а) 2010-04-21T19:23:00+04:00 10 лет, 11 месяцев назад
44

Как насчет этого подхода:


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

ответил(а) 2010-04-21T19:17:00+04:00 10 лет, 11 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема