我有一个大赛马数据库,我想查询。
我想要做的是创建一个新列(平均草皮速度),以便在当天比赛之前和特定比赛类型(草坪)中找到马的平均速度(仅过去1年)。
我以前在excel中使用averageifs formular来做这个,但是有了这么多的数据,程序会一直冻结并挂起,所以我打算转移到sql。
我已经采用了一个非常小的样本并将其简化为演示目的,我知道它将包含许多空值,但希望您理解我的问题。
因此,例如,如果我们在2015年5月21日的最后一场比赛中看到Aazif他在那天比赛之前的平均速度我们会忽略第一场比赛,因为它超出了日期范围和错误的比赛类型但我们会从第二场和第三场比赛拿下70和40分,平均给我们55分
Date and time Horse Race Type Speed Rating Average Turf Speed
10/05/2013 14:00 Aazif AW 60
10/05/2013 14:00 Bix AW 50
10/05/2013 14:00 Camelot AW 40
15/08/2014 15.00 Aazif Turf 70
15/08/2014 15.00 Bix Turf 60
15/08/2014 15.00 Camelot Turf 50
17/05/2015 13.00 Aazif Turf 40
17/05/2015 13.00 Bix Turf 30
17/05/2015 13.00 Camelot Turf 20
21/05/2015 14.00 Aazif Turf 50
21/05/2015 14.00 Bix Turf 40
21/05/2015 14.00 Camelot Turf 30
答案 0 :(得分:1)
我不确定您对大型数据库的定义"对数据库引擎来说很大。通常我会通过更高效的左连接来做到这一点,但是在那天的比赛之前你会给出一个很难的标准"这使得以这种方式编写变得困难。所以我在下面有一个可以提供你想要的东西,但可能会出现性能问题,因为组成最后一列的子查询([Prev Speed Rating])会触发每一行。如果速度很慢,首先尝试使用where子句中使用的列进行复合索引。
create view vHorseResults
as
select a.Horse,
a.[Race Type],
a.[Speed Rating],
a.[date and time],
(select avg(b.[Speed Rating])
from Races b
where a.Horse = b.Horse
and a.[Race Type] = b.[Race Type]
and a.[date and time] > b.[date and time]
and b.[date and time] >= dateadd(year, -1, getdate())
as [Prev Speed Rating]
from Races a
-- show 1 years worth of data.
select *
from vHorseResults
where getdate() >= datediff(year,-1,[date and time])
答案 1 :(得分:0)
select avg([turf speed])
where
[date and time] between [date and time]
and datediff(d,-365,[date and time])
and type='turf'
答案 2 :(得分:0)
select Horse, [Race Type], avg([turf speed])
from table
where [date and time] >= DateAdd(yy, -1, GetDate())
group by Horse, [Race Type]
答案 3 :(得分:0)
使用此
--create temp table for data sample
DECLARE @yourdata AS TABLE
(
[Date and time] DATETIME ,
Horse NVARCHAR(30) ,
[Race Type] NVARCHAR(30) ,
[Speed Rating] FLOAT
)
INSERT INTO @yourdata
( [Date and time], Horse, [Race Type], [Speed Rating] )
VALUES ( '2013-05-10 14:00:00', 'Aazif', 'AW', 60 ),
( '2013-05-10 14:00:00', 'Bix', 'AW', 50 ),
( '2013-05-10 14:00:00', 'Camelot', 'AW', 40 ),
( '2014-05-15 15:00:00', 'Aazif', 'Turf', 70 ),
( '2014-05-15 15:00:00', 'Bix', 'Turf', 60 ),
( '2014-05-15 15:00:00', 'Camelot', 'Turf', 50 ),
( '2015-05-17 13:00:00', 'Aazif', 'Turf', 40 ),
( '2015-05-17 13:00:00', 'Bix', 'Turf', 30 ),
( '2015-05-17 13:00:00', 'Camelot', 'Turf', 20 ),
( '2015-05-21 14:00:00', 'Aazif', 'Turf', 50 ),
( '2015-05-21 14:00:00', 'Bix', 'Turf', 40 ),
( '2015-05-21 14:00:00', 'Camelot', 'Turf', 30 )
--Final query
--1. Ignore the last race
--2. Ignore the race with wrong race type
SELECT T.Horse ,
AVG(T.[Speed Rating]) AS [Average Turf Speed]
FROM ( SELECT * ,
ROW_NUMBER() OVER ( PARTITION BY Y.Horse, Y.[Race Type] ORDER BY Y.[Date and time] DESC ) AS RN
FROM @yourdata AS Y
) AS T
WHERE T.[Race Type] = 'Turf'
AND T.RN <> 1
GROUP BY T.Horse
输出
如果需要在最后一次未被忽视的比赛中获得一年的平均值,请使用:
--Final query
--1. Ignore the last race
--2. Ignore the race with wrong race type
--3. get average in one year range from the last not ignored race
SELECT Y.Horse ,
AVG(Y.[Speed Rating]) AS [Average Turf Speed]
FROM ( SELECT * ,
ROW_NUMBER() OVER ( PARTITION BY Y.Horse, Y.[Race Type] ORDER BY Y.[Date and time] DESC ) AS RN ,
MAX(Y.[Date and time]) OVER ( PARTITION BY Y.Horse,
Y.[Race Type] ) AS newlast
FROM @yourdata AS Y
) Y
WHERE CONVERT(DATE, Y.[Date and time]) BETWEEN CONVERT(DATE, DATEADD(YEAR,
-1, Y.newlast))
AND CONVERT(DATE, Y.newlast)
AND Y.RN <> 1
AND Y.[Race Type] = 'Turf'
GROUP BY Y.Horse
输出
答案 4 :(得分:0)
DECLARE @Table table
(
[DateTime] datetime,
Horse varchar(20),
RaceType varchar(40),
Speed int
)
INSERT @Table VALUES
(CONVERT(datetime, '10/05/2013 14:00',103),'Aazif','AW','60'),
(CONVERT(datetime, '10/05/2013 14:01',103),'Bix','AW','50'),
(CONVERT(datetime, '10/05/2013 14:02',103),'Camelot','AW','40'),
(CONVERT(datetime, '15/08/2014 15:00',103),'Aazif','Turf','70'),
(CONVERT(datetime, '15/08/2014 15:00',103),'Bix','Turf','60'),
(CONVERT(datetime, '15/08/2014 15:00',103),'Camelot','Turf','50'),
(CONVERT(datetime, '17/05/2015 13:00',103),'Aazif','Turf','40'),
(CONVERT(datetime, '17/05/2015 13:00',103),'Bix','Turf','30'),
(CONVERT(datetime, '17/05/2015 13:00',103),'Camelot','Turf','20'),
(CONVERT(datetime, '21/05/2015 14:00',103),'Aazif','Turf','50'),
(CONVERT(datetime, '21/05/2015 14:00',103),'Bix','Turf','40'),
(CONVERT(datetime, '21/05/2015 14:00',103),'Camelot','Turf','30')
SELECT
*
FROM
@Table data
OUTER APPLY
(
SELECT AVG(Speed) AS AverageSpeedOfPreviousYear
FROM @Table
WHERE
[DateTime] < data.[DateTime]
AND DATEDIFF(YEAR, [DateTime], data.DateTime) <= 1
AND Horse = data.Horse
AND RaceType = data.RaceType
) avg
<强>结果强>
DateTime Horse RaceType Speed AverageSpeedOfPreviousYear
----------------------- -------------------- -------- ----------- --------------------------
2013-05-10 14:00:00.000 Aazif AW 60 NULL
2013-05-10 14:01:00.000 Bix AW 50 NULL
2013-05-10 14:02:00.000 Camelot AW 40 NULL
2014-08-15 15:00:00.000 Aazif Turf 70 NULL
2014-08-15 15:00:00.000 Bix Turf 60 NULL
2014-08-15 15:00:00.000 Camelot Turf 50 NULL
2015-05-17 13:00:00.000 Aazif Turf 40 70
2015-05-17 13:00:00.000 Bix Turf 30 60
2015-05-17 13:00:00.000 Camelot Turf 20 50
2015-05-21 14:00:00.000 Aazif Turf 50 55
2015-05-21 14:00:00.000 Bix Turf 40 45
2015-05-21 14:00:00.000 Camelot Turf 30 35