I have the following table:
+-----------+----------+-------------+----------------+---------------+
| FirstName | LastName | SessionDate | SessionTitle | TotalDistance |
+-----------+----------+-------------+----------------+---------------+
| Player | Striker | 05.08.2020 | Entire Session | 10.0 |
| Player | Striker | 05.08.2020 | 1v1 | 5.0 |
| Player | Striker | 06.08.2020 | Entire Session | 12.0 |
| Coach | Defender | 06.08.2020 | Entire Session | 7.0 |
+-----------+----------+-------------+----------------+---------------+
What I need to do is to calculate the average for totalDistance, for each player individually. The average should only be calculated with values, where the SessionTitle is 'EntireSession' and only for the last 50 days including the date of the row for each row. So the expected result would look like this:
+-----------+----------+-------------+----------------+---------------+---------+
| FirstName | LastName | SessionDate | SessionTitle | TotalDistance | average |
+-----------+----------+-------------+----------------+---------------+---------+
| Player | Striker | 05.08.2020 | Entire Session | 10.0 | 10.0 |
| Player | Striker | 05.08.2020 | 1v1 | 5.0 | 10.0 |
| Player | Striker | 06.08.2020 | Entire Session | 12.0 | 11.0 |
| Coach | Defender | 06.08.2020 | Entire Session | 7.0 | 7.0 |
+-----------+----------+-------------+----------------+---------------+---------+
I tried something like this, but it is awfully slow, when more rows are added:
SELECT t1.FirstName,
t1.LastName,
t1.SessionDate,
t1.SessionTitle,
t1.TotalDistance,
(SELECT (AVG(t2.TotalDistance) FROM myTable t2 WHERE t1.FirstName = t2.FirstName AND t1.LastName = t2.LastName AND t2.SessionTitle = 'EntireSession' AND t2.SessionDate <= DATEADD(DAY,50,t1.SessionDate)) as average
FROM myTable t1
It is running on a Azure SQL-Server How would be the fastest way to get this done in a select statement?
Thanks in advance!
This is your query:
SELECT t1.FirstName, t1.LastName, t1.SessionDate, t1.SessionTitle,
t1.TotalDistance,
(SELECT AVG(t2.TotalDistance)
FROM myTable t2
WHERE t1.FirstName = t2.FirstName AND
t1.LastName = t2.LastName AND
t2.SessionTitle = 'EntireSession' AND
t2.SessionDate <= DATEADD(DAY,50,t1.SessionDate)
) as average
FROM myTable t1;
First, you can try adding an index on (FirstName, LastName, SessionDate, SessionTitle, TotalDistance)
.
Second, this looks a bit like like a window function to me. If you have data on every day, then you can use:
select t.*,
avg(case when SessionTitle = 'EntireSession' then TotalDistance end) over (
(partition by FirstName, LastName
order by SessionDate
rows between unbounded preceding and 50 following
)
from myTable t;
You can simply achieve this by
SELECT FirstName, LastName, avg([TotalDistance])
FROM myTable
WHERE SessionDate>= DATEADD(Day, -50, getdate())
AND SessionTitle = 'EntireSession'
GROUP BY FirstName, Last Name
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.