SQL datetime близость к набору - PullRequest
1 голос
/ 22 ноября 2010

сервер: sql 2008 R2;набор данных: от 50 до 100 миллионов записей

У меня есть таблица, полная экземпляров скорости для транспортных средств, из которой мне нужно определить среднюю скорость всех автомобилей (то есть одно число, а не число для каждого автомобиля).Хитрость в том, что записи охватывают большой период времени, и нет никакой согласованности со временем, когда записи были записаны, поэтому у меня может быть запись в 8:15 для автомобиля и ничего снова до 8:20, тогда как другая машина может иметь записиза каждые 10 секунд в течение этого периода времени.

Учитывая конкретную дату и время, мне нужно определить эту среднюю скорость, и, поскольку она, скорее всего, не будет прямого соответствия между данным временем и записью для этогоавтомобиль, мне нужно выбрать скорость из записи, ближайшей к данному времени.

Вот сценарий установки

CREATE TABLE [dbo].[SpeedRecords](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [CarId] [int] NOT NULL,
    [TimeOfEntry] [datetime] NOT NULL,
    [Speed] [real] NOT NULL,
 CONSTRAINT [PK_SpeedRecords] PRIMARY KEY CLUSTERED ([Id] ASC))
go
insert into SpeedRecords(CarId,TimeOfEntry,Speed)
select 1, '11/22/2010 08:16:13', 67.56 union
select 1, '11/22/2010 08:15:23', 63.87 union
select 1, '11/22/2010 08:36:33', 45.66 union
select 1, '11/22/2010 08:23:43', 56.87 union
select 2, '11/22/2010 08:36:53', 78.66 union
select 2, '11/22/2010 08:04:03', 34.88 union
select 2, '11/22/2010 08:08:51', 23.23 union
select 2, '11/22/2010 08:34:52', 65.87 union
select 3, '11/22/2010 08:58:43', 45.34 union
select 3, '11/22/2010 08:34:56', 73.23 union
select 3, '11/22/2010 08:12:34', 12.87 union
select 4, '11/22/2010 08:45:12', 66.45 union
select 4, '11/22/2010 08:36:34', 90.87 union
select 4, '11/22/2010 08:24:23', 34.89 union
select 4, '11/22/2010 08:45:12', 45.83


declare @dt datetime = '11/22/2010 08:43:14'
-- select the average speed (for all cars) but 
-- only use the record for each car closest to 
-- the given datetime (@dt)

1 Ответ

1 голос
/ 22 ноября 2010

Используйте ABS (DATEDIFF ..), чтобы вычислить наименьшую разницу, ЗАкажите на этом, ограничьте.

Измените ROW_NUMBER () на DENSE_RANK () , если вы хотите получить среднее значение из 2 скоростейкоторые отличаются от @ dt

declare @dt datetime = '11/22/2010 08:43:14'
-- select the average speed (for all cars) but 
-- only use the record for each car closest to 
-- the given datetime (@dt)

;WITH Closest AS
(
     SELECT
        Speed,
        ROW_NUMBER() OVER(PARTITION BY ID ORDER BY ABS(DATEDIFF(second,@dt,TimeOfEntry))) AS Ranking
     FROM
        SpeedRecords

)
SELECT
    AVG(Speed)
FROM
    Closest
WHERE
    Ranking = 1

Для SQL Server 2000 вам понадобится коррелированный подзапрос и TOP, но это будет неудобно

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...